Search code examples
algorithmlanguage-agnosticdynamic-programming

Maximum product cutting algorithm


I am looking at the problem posted on https://www.geeksforgeeks.org/maximum-product-cutting-dp-36/#:~:text=Given%20a%20rope%20of%20length,is%20more%20than%202%20meters.

The problem statement is

Given a rope of length n meters, cut the rope in different parts of integer lengths in a way that maximizes product of lengths of all parts. You must make at least one cut. Assume that the length of rope is more than 2 meters.

It can be fairly simply solved with dynamic programming. This is their solution

// A Dynamic Programming solution for Max Product Problem 
int maxProd(int n) 
{ 
   int val[n+1]; 
   val[0] = val[1] = 0; 
   
   // Build the table val[] in bottom up manner and return 
   // the last entry from the table 
   for (int i = 1; i <= n; i++) 
   { 
      int max_val = 0; 
      for (int j = 1; j <= i/2; j++) 
         max_val = max(max_val, (i-j)*j, j*val[i-j]); 
      val[i] = max_val; 
   } 
   return val[n]; 
}

My question is, why is it valid for the inner loop to only go to i/2 instead of i - 1? This seems to be taken advantage of symmetry. However the max function is also over j * val[i - j], and it seems we are disgarding j = i/2 + 1, ..., i - 1.


Solution

  • Explanation to the algorithm given by the problem source:

    We can see that there are many subproblems which are solved again and again. Since same subproblems are called again, this problem has Overlapping Subproblems property.... Like other typical Dynamic Programming(DP) problems, recomputations of same subproblems can be avoided by constructing a temporary array val[] in bottom up manner.

    Although this does technically explain the reasoning, the explanation does not show everything. The original writer did not explain their thought process for the actual code very well. So the best any one could do would be to guess at what they were thinking. If you look at only the i<=5 cases, one could argue that the writer saw that symmetry and cut it off. This argument can be substantiated by the fact that they used the n=5 case as the example in the post.

    To explain further, the following image shows the output of the max function as the loops iterate. The yellow indicates iterations that would be skipped by having the j <= i/2 as opposed to j <= i. The j=0 row represents the val array before the loops begin and the '-' value indicates an uninitialized value.

    enter image description here

    These results will also show how they further simplified the program. The results show that for every i greater than 4, the maximum value is always in the j=3 row.

    If we see some examples of this problems, we can easily observe following pattern. The maximum product can be obtained be repeatedly cutting parts of size 3 while size is greater than 4, keeping the last part as size of 2 or 3 or 4. For example, n = 10, the maximum product is obtained by 3, 3, 4. For n = 11, the maximum product is obtained by 3, 3, 3, 2.