三种背包问题总结
1. 01背包问题
问题:假设有n件物品且有相应的价值v,与重量w,有一个容量为m的背包,每件物品只可以使用一次,求怎么装这些物品,可以使背包中的价值最高
二维:
dp[i][j] = max(dp[i-1][j],dp[i-1][j-w[i] + v[i])
转换到一维,为保证每件物品只使用一次,注意看j的变化为从后向前:
for(int i=1;i<=n;++i)
for(int j=m;j>=w[i];--j)
dp[j] = max(dp[j],dp[j-w[i]]+v[i]);
2. 完全背包
问题:在01背包的基础上,不限制可以选用的物品的数量了,这里正好可以让j从小往大遍历,这样正好可以模拟出物品可以被重复使用的情况
for(int i=1;i<=n;++i)
for(int j=w[i];j<m;++j)
//注意这样遍历,后边出现的重量j会用得到之前已经更新的值,相当于物品被重复使用;
dp[j] = max(dp[j],dp[j-w[i]]+v[i]);
3. 多重背包
问题:在01背包的基础上,规定了每种物品的数量n
for(int i=1;i<=n;++i)
for(int j=m;j>=w[i];--j)
for(int k =0;k<=n[i];++k)
if(j - k*w[i] < 0)
break
else
dp[j] = max(dp[j],dp[j-k*w[i]]+k*v[i]);
对于背包问题的转化,个人理解是,不论怎样,是给你一堆东西,这些东西有重量,或者是有价值,或者是数量有限,然后在一定的限制下,比如背包的可以容纳的重量的限制,去完成一个任务,使任务最佳,比如,背包中价值最大,背包可以被完全装满,装满书包且数量最少。。。。。诸如此类问题