- chjshen 的博客
基础算法-完全背包
- 2023-5-31 20:38:04 @
1、完全背包问题
有一个容量为V的背包和N种物品,第i种物品的体积是c[i],价值是w[i]。每种物品都有无限件可用,求将哪些物品装入背包使得价值总和最大。
2、状态转移方程
对于第i件物品,01背包的关键在于取或不取,而完全背包就有取0件、1件、...k件(k<=v/c[i])的选择,因此状态方程为:
dp[i][j] = max(dp[i-1][j-k*c[i]] + k*w[i]), 0<=k<=j/c[i]
3、物品拆分
把第i件物品拆分成多个物品,体积为c[i]*2^k,价值为w[i]*2^k,其中k满足c[i]*2^k<=v,这样,完全背包问题就转化成了01背包问题,即每个物品只能选或者不选。
这样拆分的依据:对于第i件物品,不管选择几件,都可以用若干个2^k的和。例如:
0 = 都不选
1 = 2^0
2 = 2^1
3 = 2^1 + 2^0
4、一维状态
类似01背包的一维状态,区别在于内层循环(容量)为正向c[i]..v。
for 1..n
for c[i] .. v
dp[j]=max(dp[j], dp[j-c[i]]+w[i])
5、装满问题
如果题目要求“恰好装满”,和01背包一样,只需要把除dp[0][0]外的其它dp[0][j]都初始化为-inf即可。
在某个状态计算时,假如装不满的结果是-inf,当计算max时,就会被淘汰出去。