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

多重背包


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

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