背包问题
一个背包总容量为V, 现在有N个物品, 第i个物品容量为weight[i], 价值为value[i], 现在往背包里面装东西, 怎样装才能使背包内物品总价值最大.主要分为3类:
1. 0-1背包, 每个物品只能取0个,或者1个.
2. 完全背包, 每个物品可以取无限次.
3. 多重背包, 每种物品都有个数限制, 第i个物品最多可以为num[i]个.
求解思路
利用动态规划(dynamic programming)求最优值的方法,当前状态的最优值可以转化成上一个状态的最优值,与上一个状态转移到当前状态代价的组合求最值。f[i]表示当前状态的最优值,f[i-1]表示上一个状态的最优值,s(i-1, i)表示从状态i-1转移带状态i的代价。则: f[i] = max{f[j], f[j]+s(i-1, i)}
具体问题分类
背包问题可以根据物品个数的限制,有多种情况0-1背包,完全背包,多重背包。
0-1背包问题
0-1背包表示每个物品只有取和不取的状态,即只能取0个或1个。
用子问题定义状态:即f[i][j]表示前i间物品恰放入一个容器为j的背包可以获得的最大价值。状态转移方程为:
f[i][j] = max{f[i-1][j], f[i-1][j-weight[i]]+value[i]}
C代码实现如下:
1 for(int i=1;i<=n;i++) // i、n分别表示物品编号、总物品数 2 { 3 for(int j=m;j>=0;j--) // j、m分别表示剩余容量、总容量 4 { 5 if(j>=weight[i]) // weight[i]表示物品 i 的质量 6 f[j]=max(f[j],f[j-weight[i]]+v[i]); // v[i] 表示物品 i 的体积 7 } 8 }