01背包与完全背包(dp复习)

01背包和完全背包都是dp入门的经典,我的dp学的十分的水,借此更新博客的机会回顾一下

01背包:给定总容量为maxv的背包,有n件物品,第i件物品的的体积为w[i],价值为v[i],问如何选取才能是背包内的物品价值总和最大。

stdin:

5

1 2 3 4 5

5 4 3 2 1

stdout:

14

设dp[i][j]为取前i件物品时容量为j的最优解。

状态转移方程:dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);

压缩后:dp[j]=max(dp[j],dp[j-w[i]]+v[i]);

for (int i = ; i <= n; i++) {
for (int j = ; j <= maxv; j++) {
if (j < w[i])
dp[i][j] = dp[i - ][j];
else
dp[i][j] = max(dp[i - ][j], dp[i - ][j - w[i]] + v[i]);
}
}//二维dp
for (int i = ; i <= n; i++) {
for (int j = maxv; j >= w[i]; j--) {
dp[j] = max(dp[j], dp[j - w[i]] + v[i]);
}
}//一维

完全背包:在01背包的基础上,每件物品都不限次数。

从一维数组上区别0-1背包和完全背包差别就在循环顺序上,0-1背包必须逆序,因为这样保证了不会重复选择已经选择的物品,而完全背包是顺序,顺序会覆盖以前的状态,所以存在选择多次的情况,也符合完全背包的题意。状态转移方程都为dp[j] = max(dp[j],dp[j-w[i]]+v[i])。

for(int i=; i<=n; i++)
for(int j=w[i]; j<=maxv; j++)
f[j]=max(f[j],f[j-w[i]]+c[i]);
上一篇:Bone Collector(复习01背包)


下一篇:九度OJ 1123:采药 (01背包、DP、DFS)