1. 开心的金明
裸的01背包
for(int i = 1; i <= m; i ++)
for(int j = n; j >= f[i].mon; j --)
dp[j] = max(dp[j] , dp[j - f[i].mon] + f[i].val);
2.小A点菜
01背包
dp[0] = 1; //!!!
for(int i = 1; i <= m; i ++)
for(int j = n; j >= f[i].mon; j --)
dp[j] = dp[j] + dp[j - f[i].mon];
3.金明的预算方案
有依赖的背包 思路为 将不能直接购买的物品与可直接购买的物品区分开 题中已知附属品最多为2个 所以可以设置两个数组来保存附属品信息
在DP核心代码中 需考虑 只购买主物品、购买主物品及附属品1、购买主及附2、都购买的情况;
for(int i = 1; i <= m; i ++)
for(int j = n; j >= main[i].mon; j --) {
if(j - main[i] .mon >= 0) dp[j] = max(dp[j], dp[j - main[i].mon) + main[i].val); //主
if(j - main[i].mon - f1[i].mon >= 0) dp[j] = max(dp[j], dp[j - main[i].mon - f1[i].mon) + main[i].val + f1[i].val);//主 + 附属品1
..... //主 + 附属品2
..... //主 + 附属品1 、2
}
4.采药
裸01背包
5.装箱问题
依旧01背包
6.疯狂的采药
在4.采药的基础上规定每种草药可以无限采摘 其实就是把01背包变成完全背包
for(int i = 0; i < m; i ++)
for(int j = f[i].time; j <= n; j ++) //此层与01循环顺序相反 每个元素可重复利用
dp[j] = max(dp[j], dp[j - f[i].time] +f[i].val;
总结:
1、01和完全区别就在于核心代码的循环的第二层 顺序相反
2、有依赖的背包问题应主、附分开;
3、多重背包可转化为01背包,在其核心代码第二行之前增加一行
for(int j = 0; j < f[i].num; j ++)