• 背包问题更深化的理解-多重背包的二进制拆分


    这篇文章主要证明一下多重背包的二进制拆分的可行性与正确性:

    类似于二进制的原理:一定可以表达一系列连续的正数,下面用例子证明

           把22进行二进制拆分:

             成为1,2,4,8,7;由1,2,4,8可以组成1--15之间所有的数,而对于16--22之间的数,可以先减去剩余的7,那就是1--15之间的数可以用1,2,4,8表示了。

    例题:

    NOI 8756:砝码称重V2

    总时间限制: 
    1000ms
     
    内存限制: 
    65536kB
    描述

    设有1g、2g、3g、5g、10g、20g的砝码各若干枚(其总重<=100,000),要求:计算用这些砝码能称出的不同重量的个数,但不包括一个砝码也不用的情况。

    输入
    一行,包括六个正整数a1,a2,a3,a4,a5,a6,表示1g砝码有a1个,2g砝码有a2个,……,20g砝码有a6个。相邻两个整数之间用单个空格隔开。
    输出
    以“Total=N”的形式输出,其中N为可以称出的不同重量的个数。
    样例输入
    1 1 0 0 0 0
    样例输出
    Total=3
    提示
    样例给出的砝码可以称出1g,2g,3g三种不同的重量。
    注意:对于拆分剩余是0,因题目的意思要特别处理。
    #include<iostream>
    using namespace std;
    #include<cstdio>
    int a[]={0,1,2,3,5,10,20};
    #define MAX 100100
    bool f[MAX];
    int val[MAX];
    int t=0;
    int sum=0;
    void input()
    {
        int count=0,b=0;
        for(int i=1;i<=6;++i)
        {
            scanf("%d",&b);
            sum+=b*a[i];
            count=a[i];
            if(b>1)
            {
                for(int i=1;i<=b;i<<=1)
                {
                    ++t;
                    val[t]=count*i;
                    b-=i;
                }
                if(b>0)
                {
                    ++t;
                    val[t]=count*b;
                }
                continue;
            }
             
            if(b==1)
            {
                ++t;
                val[t]=count;
            }
        }
    }
    void DP()
    {
        f[0]=true;
        for(int i=1;i<=t;++i)
          for(int j=sum;j>=val[i];--j)
          f[j]=f[j]||f[j-val[i]];/*注意val才是拆成的背包*/
        int p=0;
        for(int i=1;i<=sum;++i)
        if(f[i])
        p++;
        printf("Total=%d
    ",p);
    }
    int main()
    {
        input();
        DP();
        return 0;
    }
    View Code

      

  • 相关阅读:
    linux下清空文件的几种方式以及对比
    远程桌面连接无法验证您希望连接的计算机的身份-mac连接远程桌面
    Linux配置临时IP和网关命令
    linux(centos、ubuntu)网卡配置文件不生效
    负载均衡
    Zookeeper基础使用机制原理
    高性能RPC框架选型
    事务隔离机制
    一致性协议Raft
    机器学习入门
  • 原文地址:https://www.cnblogs.com/c1299401227/p/5361718.html
Copyright © 2020-2023  润新知