洛谷刷题记录 2-15 背包

洛谷链接

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 ++) 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值