多重背包二进制原理拆分问题

多重背包


也就是说限定物品选择的个数。

vi ci ki //对于第i个物品,体积为vi,价值ci,只能选择ki次。

① 将 ki 分为 ki 个物品,然后用01背包解决。
   代码:
      for (int i=1;i<=n;i++)
         {
            scanf("%d%d%d",&v,&c,&k);
             for (int j=1;j<=k;j++)
                 s[++cnt].v=v,s[cnt].c=c;
          }
② 采用类似lca的方法,将k个物品分为 1,2,4,8,16,..... 2^n.
   这样对于每一个1-ki之间自然数i都可以被组合出来。然后再采用01背包。

   二进制拆分一定要覆盖当前的点。
   代码:
       while (n--)     //接下来输入n中这个物品 
         { 
             scanf("%d%d%d", &vi, &ci, &ki);  //输入每种物品的数目和价值 
             for (int k=1; k<=ki; k<<=1)   //<<左移相当于乘二 
              { 
                value[cnt]=k*vi;//体积  每个二进制分法的物品体积和价值都要×k
                size[cnt++]=k*ci;//价值 
                ki-=k; 
              } 
            if (ki>0)  //如果最后ki分割有剩余,那么就把剩余的当做一种情况
              { 
                value[cnt]=ki*vi; 
                size[cnt++]=ki*ci; 
              } 

转载于:https://www.cnblogs.com/c1299401227/p/5370701.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值