我试图通过动态编程来解决标准切杆问题。如找到here和here,重现关系似乎是:
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])
}
}
而array[n]
会返回n
的值,这是我们的答案。我的问题在于
array[i] = max(array[i],prices[j]+array[i-j])
不应该是
array[i] = max(array[i],array[j]+array[i-j])
想象一下,我们正在尝试查找长度8
的最大值。现在,对于4
,我们发现通过剪切一个长度为4
的单个单位获得的值小于通过缩短3
和1
的长度获得的值,即n = 4
,prices[4]
不是最佳选择。但由于我们正在自下而上构建结果数组,array[4]
是最佳的。与array[4]+array[4]
相比,n = 8
的最大值不是prices[4]+array[4]
吗?我得到的解决方案看起来像这样:
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]
}
}
如果这不正确,请告诉我我在哪里逻辑错误。
答案 0 :(得分:1)
array[i] = max(array[i],prices[j]+array[i-j])
看起来对我来说。
在该算法中,j
表示初始切割的杆长度。我们从一根长度为i
的杆开始,并切断j
。然后,我们需要知道我们可以获得i - j
一根杆的数量,因为你只是切断了j
长度并且你被i - j
留下了。但是我们知道这个值至少和price[i-j]
一样高,因为我们可以选择将杆作为一个整体出售,或者通过切割它来增加它的价值。
实施例: 我们有一个长度为4的杆。假设array []已经包含1,2,3的最佳值,那么我们:
切掉一段长度为1的长度,然后检查我们可以得到多少长度为3的杆
切断一段长度2,然后检查我们能得到多少 对于长度为2的杆
切掉一块长度为3的长度,然后检查我们可以得到多少长度为1的杆
并选择最大值。
如果我们使用array[i] = max(array[i],array[j]+array[i-j])
array[k]
包含长度为k的杆的最大值,如果我们将其切成碎片。因此,与使用price[k]
时相比,这些值会出乎意料地高。
此外,递归中的当前步骤仅关注进行一次切割,并检查剩余的最大值,而不是双方最大值(当您发现大切割的值时将会处理)可能不太理想)