NOKIA - Editorial

PROBLEM LINKS:

Practice
Contest

DIFFICULTY

Simple

PREREQUISITES

arrays, divide-and-conquer, recursion

PROBLEM

Given an array A[0…N+1], consider the indices [1…N] as spots for the soldiers and index 0 as the left tower and the index N+1 as the right tower. Initially set A[0] = 1, A[N+1] = 1 and rest all have 0s. Given a permutation P[1…N] of the indices {1, 2,…,N}, we fill them with 1s in that order and find the length of used wire as follows.

used_length = 0 for i = 1 to N used_length += ( distance from index P[i] to nearest index having 1 to left ); used_length += ( distance from index P[i] to nearest index having 1 to right ); A[ P[i] ] = 1;

You can see that the used_length depends on the permutation P and given an integer M, we need to find the minimum length of unused wire. It is same as asking for the maximum possible used_length ≤ M for some permutation P. If M is not sufficient for any permutation P, output -1.

QUICK EXPLANATION

If you have solved the problem or almost got it yourself, this explanation is for you. If you have not solved it and eager to know how to build the idea from scratch, skip this part and go to the Detailed explanation section below.

There is a simple bruteforce solution and other clever solution. They are explained below.

  1. N = 30 is so small that you can generate all possible used_lengths for each N = 1 to 30. For a given N, we just need to fix the first position and that partitions the problem in to two independent smaller subproblems and we can merge the answers to these smaller subproblems. If we consider the number of possible used_lengths for a given N to be of order O(N2), this requires time O(N5), which is fast enough for N = 30.

  2. Given N, we can find the minimum and maximum used_lengths.

For minimum, its always better to try partitioning the problem into two equal subproblems.
minLen[n] = (n+1) + minLen[n/2] + minLen[n-1-n/2]

For maximum, we just need to place in the order {1,2,3…N}
maxLen[n] = (n+1) + maxLen[n-1] , this is same as maxLen[n] = (n(n+3))/2*

Now, can you prove that all the values between [ minLen[n], maxLen[n] ] are possible ? An idea is given in tester’s approach.

DETAILED EXPLANATION

If you haven’t solved this problem yet, take some time now and try different cases on paper. eg. Consider N = 4 and try to find all possible sum_of_lengths for different permutations of {1,2,3,4}. You can also take a look at the explanation of sample cases under the problem statement for better understanding.

First lets see an almost bruteforce solution. Consider the array A for N = 9.
Initially A = |, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
and we need to fill the array with 1s in some order. Suppose if we set A4 = 1,
then A = |, 0, 0, 0, 1, 0, 0, 0, 0, 0, |
and length of wire on left side = 4, length of wire on right side = 6, so we need wire of length 4 + 6 = 10.

Note that if we place the first soldier among N spots at any index, we need wire of length (N+1). Not only that, the first soldier now acts as a barrier between his left and right sides. There will never be a wire which cross this soldier. So we have two independent problems now. If the first solder is placed at index I, then we need (N+1) length wire for this soldier and solve subproblem with (I-1) spots on left side and subproblem with (N-I) spots on right side.
A = |, 0, 0, 0, 1, 0, 0, 0, 0, 0, | is same as solving
A = |, 0, 0, 0, | and |, 0, 0, 0, 0, 0, |

So we can store all possible values for each N = 1 to 30, and for a given N try all possible positions for the first soldier and mix the answers of the two independent subproblems to get all possible values. As the constraint on N is 30, you can just bruteforce each of these steps.

For an alternate simple approach, see point 2 in the quick explanation section.

SETTER’S SOLUTION

Can be found here

APPROACH

The problem setter used the approach given in the detailed explanation above.

TESTER’S SOLUTION

Can be found here

APPROACH

The problem setter and the tester have independently observed that each of the values between [min, max] can be achieved for some permutation P. This method takes only O(N) time. Here is a rough idea of the proof using induction, in tester’s words.

max[0] = min[0] = 0

max[n] = max[n-1] + n+1

min[n] = min[n/2] + min[n - n/2 - 1] + n+1

Therefore max[n] = n * (n+3) / 2, min[n] = O(n log n).

Here we assume that for k = 1,2,…,n-1, [ min[k], max[k] ] are all possible,

then we should prove [ min[n], max[n] ] are all possible.

From min[n/2] + min[n - n/2 - 1] + n+1 to max[n/2] + max[n - n/2 - 1] + n+1 are all possible by the assumption.

If min[a+1]+min[n-a-2] ≤ max[a]+max[n-a-1] for all a=n/2, n/2+1, …, n-2, then we can show
[ min[n], max[n] ] are all possible.

L.H.S. = O(n log n), R.H.S = O(n^2), therefore, this is correct for large n.

If you can come with a more intuitive and simple proof, please edit this post and add a section ‘Alternate Proof’.

16 Likes

Here this function calculates the minimum value for a given N.

mid=N/2 if n is even and mid=N/2+1 if n is odd …Please tell me if anything is wrong in this function.

            int findmin(int mid,int n)
            {
                int i,j,k,begin,sum=0;
                begin=n;
                 while((begin>mid))
                 {
                      sum=sum+(begin-mid)+1;
                     // printf("sum=%d\n",sum);
                     begin--;
                 }
                 
                 begin=1;
                 while(begin<mid)
                 {
                        sum=sum+(mid-begin)+1;
                        // printf("sum=%d\n",sum);
                        begin++;
                 }
                 sum=sum+(n+1);
               return sum;
            }
1 Like

Simpler way to prove/conclude this ?

“all values between [ minLen[n], maxLen[n] ] are possible”

11 Likes

“If we consider the number of possible used_lengths for a given N to be of order O(N2), this requires time O(N5)”

Can somebody tell me why does this requires time O(n^5)?? I understood that the number of possible used-lengths has to be of order O(n^2), but how does this implies that finding the used-lengths requires time O(n^5) ??

"For minimum, its always better to try partitioning the problem into two equal subproblems.
minLen[n] = (n+1) + minLen[n/2] + minLen[n-1-n/2]

For maximum, we just need to place in the order {1,2,3…N}
maxLen[n] = (n+1) + maxLen[n-1] , this is same as maxLen[n] = (n*(n+3))/2"

I didn’t understand how one can prove this. Is it a rule of thumb?

Also, can you fix the ‘?’ in the “min[a+1]+min[n-a-2] ? max[a]+max[n-a-1]”. It appears in a lot of problems statements in practice as well.

4 Likes

can anybody tell me what should be “?” in this quote :

If min[a+1]+min[n-a-2] ? max[a]+max[n-a-1] for all a=n/2, n/2+1, …, n-2, then we can show [ min[n], max[n] ] are all possible.
Blockquote

Sir, please help me with my logic for this problem.

After spending some time on this question, I came with a math expression, which I believe is correct. The main part of my method depends on the fact that for ‘n’ positions, there will be a minimum and a maximum length of cable needed to make the desired connections - this is the obvious part. Upon doing some calculations on pen-paper, I came up with the following:

if n==1:
   min=max=2

else if n==2:
   min=max=3
   
else:
   min=4*(n-1)
   max=(n*(n+3))/2

I did calculations manually uptill n=6 and things turned out correct thus far. Now, given a value of ‘m’, it will fall in either of the 3 cases:

  1. m<lo
  2. m>hi
  3. m lies between hi and lo (both inclusive)

based on that logic, the psuedocode is:

input n
if n==1:
    lo=hi=2
else if n==2:
    lo=hi=5
else:
    lo=4*(n-1)
    max=(n*(n+3))/2

input m
if m<lo:
    print -1
else if m>hi:
    print (m-hi)
else:
    print 0

Unfortunately, this gave a WRONG ANSWER. So I compared the output of my code with that of an accepted code and couldn’t find any differences.

Please help me find the flaw in the logic.

This is my submitted code ::: CodeChef: Practical coding for everyone

4 Likes

can anybody make me understand this question by giving one simpler example?

1 Like

Alternate Proof ==>

Simplest proof to prove that all [min(n),max(n)] are possible is :

case 1 : if n==1
max(1) = min(1) = 2;

case 2 : if n==2
max(2) = min(2) = 5;

case 3 : if n==3
max(3) = 9;
min(3) = 8;

So for n>3 if we go for solution then after dividing the problem we will surely reach some level where we have to solve for n’=3 and thing will be able to create the difference of 1 (if all other branches are remained constant). Hence we can get all the numbers in [min(n),max(n)].

4 Likes

Admin, can you please explain this:

If min[a+1]+min[n-a-2] ≤
max[a]+max[n-a-1] for all a=n/2,
n/2+1, …, n-2, then we can show [
min[n], max[n] ] are all possible.

Also, ( min[a+1]+min[n-a-2] ≤ max[a]+max[n-a-1] ) is false for n=4, since ( 8+0 <= 5+2 ) is false.

O(1) solution solution:

max len=(n+1)(n+2)/2

min len=ceil(log(n+1)*(n+1))

all values between max and min are possible.

2 Likes

can someone explain in brief , how to come up with this formula,
" minLen[n] = (n+1) + minLen[n/2] + minLen[n-1-n/2] " ?

3 Likes

I made my solution according to the editorial , someone please have look on code and suggest the mistakes?
I matched few test cases with the solution all good , but its always WA while submitting.

Here’s my


[1] 

Thankyou
  [1]: https://ideone.com/cCKp2G
1 Like

i got the perfect explanation of the logic used by setter, but i am not allowed to post image here. so if anyone is curious to know, can mail me @ sumeshkpandit@gmail.com

how can we say that any value between max an d min is possible?
anyone with a concrete proof for it?

It explains a naive approach previously.

“For a given N, we just need to fix the first position”

Here you have O(N) for fixing the position

“and that partitions the problem in to two independent smaller subproblems and we can merge the answers to these smaller subproblems.”

This takes O(N^4) because for each of the number of the first subproblem(O(N^2)), you can choose any number of the of the second subproblem(O(N^2)).

So for a given N, in O(N^5) you can find the number of used_lengths.

Note the following is not a proof:
Yet it can give some intuition,
f(n) = n+1 + f(n-x) + f(x), will have minima at x = n/2, u can find this by assuming f(n) to a polynomial function, and taking the derivative.
and f(n) is maximum at other two ends, that is either x = 1 or x = n-1, due to increasing both arms of parabola. (assuming the degree of polynomial f(n) is 2 ), again this is intuitive since the dip is at x=n/2.

f(n) starts decreasing as x increasing from 1 to n/2, reaches its minima when x = n/2, then again starts increasing.
1 Like

@mkagenius - the equation in the first line of your explanation should be f(n)=(n+1)+f(x)+f(n-x-1).
Further, the statement “For maximum, we just need to place in the order {1,2,3…N}” seems fairly intuitive to me. (n*(n+3))/2 is easily derivable as being equal to ((n+1)+…+2).
Regarding the one regarding minLen[n], I also am having trouble finding a satisfactory proof for it. It is no doubt intuitive, but it would be great if someone could come up with a concrete proof for the same.

1 Like

@shubh09, yes, you are right. it should be, f(n)=(n+1)+f(x)+f(n-x-1).
The rest of the things still hold.
But

"For maximum, we just need to place in the order {1,2,3...N}"
is not at all intuitive to me, the sum ((n+1)+ .. + 2) surely equals n*(n+3)/2, but is it intuitive that it will be maximum ? I am not sure.
1 Like

Let me put it this way - if the length of the wire to connect the ith soldier (meaning i-1 soldiers have already been stationed on the wall) be denoted by len[i], then one can easily see that len[i]>len[i+1]. Now, we know that len[1]=n+1. Hence, we can easily deduce that the max value for len[2] is n. Going on this way, the statement in question is evident.

1 Like