这几天一直在看背包问题,看了很久才看懂完全背包问题O(VN)的算法的原理,在此记录,防止以后忘记
这是我在看了背包九讲后总结的一种思路
完全背包问题有基本思路和改进后的O(VN)算法,这两个的状态转移方程基本都会出现在所有相关博客中
基本思路
类似于0-1背包问题,用f[i][v]
表示前i种物品放入一个容量为v的背包的最大价值
状态转移方程:
f[i][v]=max{f[i-1][v-k*c[i]]+k*w[i]|0<=k*c[i]<= v}
这应该容易理解,是在0-1背包问题的基础上得来的
O(VN)算法
用f[v]
来表示把N种物品放入容量为v的背包所得的最大价值
伪代码如下:
for v = 0 ... V do f[v] = 0
for i = 1 ... N do
for v = c[i] ... V do
f[v] = max{f[v], f[v-c[i]] + w[i]}
一种思路
这个算法可以由前面的基本思路优化而来。
首先,基本思路的状态转移方程可以优化为:
f[i][v]=max{f[i-1][v], f[i][v - c[i]] + w[i]}
这是因为f[i][v - c[i]] + w[i] = max{f[i-1][v - c[i] - k*c[i]] + k*w[i]} | 0 <= k*c[i] <= v-c[i]
这可以由基本思路的状态转移方程得来。
有了这个式子后,就容易得出O(VN)算法了,只需把空间优化成一维即可。
另外,由于算出f[i][v]
用到了第i行的值,即已被更新后的值,因此内循环要从c[i]开始遍历到V,与0-1背包问题顺序正好相反