zoukankan      html  css  js  c++  java
  • 多重背包二进制原理拆分问题

    多重背包


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

    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; 
                 

  • 相关阅读:
    2017北京网络赛 J Pangu and Stones 区间DP(石子归并)
    2017北京网络赛 F Secret Poems 蛇形回路输出
    2017 北京网络赛 E Cats and Fish
    CF 1198 A. MP3 模拟+滑动窗口
    博弈论
    gym 101911
    容器STL
    POJ 3281 Dining 最大流+拆点
    hdu 1533 Going Home 最小费用最大流 (模板题)
    C#博文搜集
  • 原文地址:https://www.cnblogs.com/c1299401227/p/5370701.html
Copyright © 2011-2022 走看看