动态规划 - 杆切割

时间:2011-08-25 23:56:09

标签: algorithm

前几天我正在看CLRS只是为了让我的思绪更加清醒,并碰到经典的切杆问题。

经典的自下而上解决方案如下:

1: let r[0..n] be a new array
2: r[0] = 0
3: for j = 1 to n
4:    q = -1
5:    for i = 1 to j
6:       q = max(q, p[i] + r[j-i])
7:    r[j] = q
8: return r[n]

现在有一些我一直在想的事情。为什么我们继续在L.6上重用p [i]?我的意思是让我们说我们有j = 4然后它会计算以下组合:

1 + 3
2 + 2
3 + 1
4 + 0

真正两次计算“3 + 1”的重点是什么。我建议的不是使用p []而只使用r []并停在楼层(j / 2)。

1: let r[0..n] be a new array
2: r[0] = 0
3: for j = 1 to n
4:    q = p[j]
5:    for i = 1 to floor(j/2)
6:       q = max(q, r[i] + r[j-i])
7:    r[j] = q
8: return r[n]

有人看到这种方法有问题吗?

谢谢,

3 个答案:

答案 0 :(得分:2)

您的优化没有任何问题。我已经看过它在杆切割问题中曾多次使用/提到过(这里只是一个例子:http://users.csc.calpoly.edu/~dekhtyar/349-Spring2010/lectures/lec09.349.pdf)。没有完美的教科书这样的东西。它可能是CLRS的一个错误,或者他们只是觉得提到这样的优化会使这本书变得混乱。

通常,这些入门书籍将专注于高级概念,并将发现这些微不足道的优化留给读者。考虑冒泡排序:不是每个人都会提到内部循环j只需要达到i的简单优化这一事实。

答案 1 :(得分:0)

我知道这是一个老问题,但我觉得这个问题只有一半回答。回答你问题的第一部分:

  

真正计算“3 + 1”的重点是什么

我想指出书中有一个脚注说明,

  

如果我们要求按照非减小尺寸的顺序切割件,   会有更少的方法来考虑。对于n = 4,我们会考虑   只有5种这样的方式。 [...]然而,我们不会进一步探讨这一调查。

您的优化没有任何问题。我认为这本书被故意排除在外,以便让学生更容易解决后续练习。

答案 2 :(得分:0)

您的优化很好。 使用单个循环而不是2个循环有一种更有效的方法:

1:let r[0..n] be a new array
2:r[0] = 0
3:q=-1
4:for j = 1 to floor(n/2)
5:q = max(q, r[j] + r[n-j])
6:r[j] = q
7:return r[floor(n/2)]