0

I am trying to solve the standard rod-cutting problem through dynamic programming. As found here and here, the recurrence relations seems to be:

prices = [1..n]
array[1..n]

array[1] = prices[1]

for i in (2..n)
{
    array[i] = INT_MIN
    for j in (1..i-1)
    {
        array[i] = max(array[i],prices[j]+array[i-j])
    }
}

And array[n] returns the value for n, which is our answer. My question lies in the line

array[i] = max(array[i],prices[j]+array[i-j])

Shouldn't it be

array[i] = max(array[i],array[j]+array[i-j])

Imagine we are trying to find max value for length 8. Now, for 4 we find that the value we obtain by cutting one single unit of length 4 is less than say obtained by cutting lengths of 3 and 1, i.e for n = 4, prices[4] is not optimal. But since we are building the result array bottom up, array[4] is optimal. So won't array[4]+array[4] be the max value for n = 8, compared to prices[4]+array[4]? My resulting solution looks something like this:

prices = [1..n]
array[1..n]

for i in (1..n)
    array[i] = prices[i] //prices[i] is the minimum value we can obtain by cutting it fully 

for i in (2..n)
{
    for j in (1..i-1)
    {
        array[i] = max(array[i],array[j]+array[i-j]) // find out all possible (j,i-j) pairs, and compare with array[i]
    }
}

If this is not correct, please tell me where am I erring logically.

SexyBeast
  • 7,913
  • 28
  • 108
  • 196

1 Answers1

1

array[i] = max(array[i],prices[j]+array[i-j]) looks right to me.

In that algorithm, j represents the length of rod of your initial cut. We start off with a rod of length i and cut off j. Then, we need to know how much we can get for a rod of i - j because you just cut off j length and you're left with i - j. But we know this value is at least as high as price[i-j] because we have the option of selling the rod as a whole or by cutting it to increase its value.

Example: We have a rod of length 4. Assuming array[] already contains optimal values for 1,2,3, then we:

cut off a piece of length 1, then check how much we can get for a rod of length 3

cut off a piece of length 2, then check how much we can get for a rod of length 2

cut off a piece of length 3, then check how much we can get for a rod of length 1

And pick the maximum.

If we used array[i] = max(array[i],array[j]+array[i-j])

array[k] contains the maximum value for a rod of length k if we cut it into pieces. So these values would be unexpectedly high compared to if we used price[k].

Also the current step in the recursion only cares about making one cut, and checking the leftover's max value, not both sides max values (that will be taken care of when you find that the value of a large cut may not be ideal)

Chris
  • 846
  • 6
  • 16
  • Sorry, I didn't get this line - `array[k] contains the maximum value for a rod of length k if we cut it into pieces. So these values would be unexpectedly high compared to if we used price[k].`. Can you please explain a bit more? – SexyBeast Mar 27 '16 at 08:10
  • Sure - Price[k] is the value of a rod of length k, as a whole. So array[k] must be at least that high, as we have the option to sell it as a whole (for price[k]) **or** potentially sell it for more if we can cut it into pieces whose values add up to more than price[k]. Also if we never consult the price array, then the value of any rod will always be price[1] * length – Chris Mar 27 '16 at 20:59
  • Umm, that's the idea, right? When I am trying to get the best cut for `n=8`, I just need to know the best combinations that can yield it. If `array[4]` is more than `prices[4]`, then obviously `prices[4]+prices[4]` will be less than `array[4]+array[4]`, isn't it? Why do I need to consult `prices[4]` at all, given that, for `n=4`, I already have the optimal solution stored in `array[4]`? The initial value of `array[4]` was already `prices[4]`, so when the final value of `array[4]` is updated, it takes into account that standalone cut as well as sub-combinations and pick the best one, right? – SexyBeast Mar 27 '16 at 22:58
  • If you initialize array[] to the values of price[] then I don't see why the second recurrence wouldn't work. Without initializing your array though it would definitely not work. – Chris Mar 28 '16 at 17:51
  • Aha, I clearly mentioned it in my question in lines 3 and 4 of my code.. :) – SexyBeast Mar 28 '16 at 19:57
  • Well, question was "shouldn't it be", to which the answer is no. You've come up with a new algorithm that works also - which is admirable, but the original works fine too without modification =). I'll admit I didn't see that difference in the new code. At any rate, I'd be interested to know if the two differ in any of their solutions - if you're interested in trying them out against eachother – Chris Mar 28 '16 at 20:41
  • That I am not sure of.. Will test it. Thanks! – SexyBeast Mar 28 '16 at 20:50