思路
01背包的模板
我的问题
优化前的转移方程
f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}
优化后的伪代码
for i=1..N
for v=V..0
f[v]=max{f[v],f[v-c[i]]+w[i]};
题解讲到:要求在每次主循环中我们以v=V..0的顺序推f[v],这样才能保证推f[v]时f[v-c[i]]保存的是状态f[i-1][v-c[i]]的值 对于这类按什么顺序推的问题该怎么思考,或者换种说法——这种递推的顺序是否跟刷表和填表的思想有关呢,感觉对这种问题没有思路
共 4 条回复
好的,谢谢老师
另外,这种对于某道题目的提问,可以到对应题目的题目板块讨论区去发帖哦。
解释
这里从 到 仅仅是为了避免重复更新,你可以看到如果是二维数组的写法,从 到 循环也是可以的。 这是因为去掉一维以后,如果你从 到 的话,你刚才更新过的值,可能马上就去更新别的值去了,这样一次循环内,你其实更新了很多轮的值。
而从 到 的顺序更新,可以保证每一次循环内,只更新了一轮的值。
例子
比如只有 个物品,价值和体积都是 ,背包的空间是 ,如果只用一维数组
f[]
计算:如果是从 到 循环的话:
i=1
的循环这里就已经不对了,因为你在一次循环内用更新过的值又去更新了别的值。
如果是从 到 循环的话:
i=1
的循环这样才是正确的。
补充
如果一定想从 到 循环的话,可以使用
滚动数组
这种方法。数组开成
f[V][2]
的,用变量cur
和pre
表示当前要更新的是哪一维、上次更新的是哪一位(取值 或 ),然后每次更新的时候写成:然后把
cur
和pre
交换就行。(初始取值可以是cur = 1, pre = 0
)