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


    多重背包


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

    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; 
                 

  • 相关阅读:
    JS DOM基础
    JS 部分常见循环、分支、嵌套练习
    记一些让footer始终位于网页底部的方法
    JS 实现banner图的滚动和选择效果
    JS 部分基础内容总结
    Flex弹性布局基础教程
    My SQL数据库的安装与配置
    网页共用头部和尾部的部分方法
    Unity3d入门 关于unity工具的熟悉
    Unity3d学习 制作地形
  • 原文地址:https://www.cnblogs.com/c1299401227/p/5370701.html
Copyright © 2020-2023  润新知