zoukankan      html  css  js  c++  java
  • coins_多重背包

    ps:原来用新浪,可是代码的排版不是很好,所以用博客园啦,先容许我把从八月份开始的代码搬过来,从这里重新出发,希望这里可以一直见证我的成长。

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 12337    Accepted Submission(s): 4925


    Problem Description
    Whuacmers use coins.They have coins of value A1,A2,A3...An Silverland dollar. One day Hibix opened purse and found there were some coins. He decided to buy a very nice watch in a nearby shop. He wanted to pay the exact price(without change) and he known the price would not more than m.But he didn't know the exact price of the watch.

    You are to write a program which reads n,m,A1,A2,A3...An and C1,C2,C3...Cn corresponding to the number of Tony's coins of value A1,A2,A3...An then calculate how many prices(form 1 to m) Tony can pay use these coins.
     
    Input
    The input contains several test cases. The first line of each test case contains two integers n(1 ≤ n ≤ 100),m(m ≤ 100000).The second line contains 2n integers, denoting A1,A2,A3...An,C1,C2,C3...Cn (1 ≤ Ai ≤ 100000,1 ≤ Ci ≤ 1000). The last test case is followed by two zeros.
     
    Output
    For each test case output the answer on a single line.
     
    Sample Input
    3 10 1 2 4 2 1 1 2 5 1 4 2 1 0 0
     
    Sample Output
    8 4
    #include<iostream>
    #include<string.h>
    using namespace std;
    const int N=100005;
    int a[N],b[N],dp[N];
    int i,j;
    int max(int a,int b)
    {
        return a<b?b:a;
    }
    
    void onepack(int c,int w,int m)
    {
       for(j=m;j>=c;j--)
           dp[j]=max(dp[j],dp[j-c]+w);
    }
    void allpack(int c,int w,int m)
    {
        for(j=c;j<=m;j++)
        {
            dp[j]=max(dp[j],dp[j-c]+w);
        }
    }
    
    
    void mulpack(int c,int w,int m,int n)
    {
        if(c*n>=m) allpack(c,w,m);
        else 
        {
            int k=1;
            while(k<n)//二进制优化,下面有具体说明
            {
                onepack(k*c,k*w,m);
                n-=k;
                k*=2;
            }
            onepack(n*c,n*w,m);
    
        }
    }
    
    int main()
    {
        int n,m;
        
        while(cin>>n>>m,n||m)
        {
            for(i=1;i<=n;i++)
                cin>>a[i];
            for(i=1;i<=n;i++)
                cin>>b[i];
            memset(dp,0,sizeof(dp));
            for(i=1;i<=n;i++)
            {
                mulpack(a[i],a[i],m,b[i]);
            }
            int cnt=0;
            for(i=1;i<=m;i++)
                if(dp[i]==i) cnt++;
            cout<<cnt<<endl;
        }
        return 0;
    }
    

      

    下面是找到一个叫老杨的人对二进制优化的理解:
     

    这是一个多重背包的模板,也是十分好用的一种模板,因为这个比直接拆除01 背包来做

    要省些时间。这是为啥呢,首先先由我讲一下为什么能换成01 背包吧。

    举个栗子吧。 假如给了我们 价值为 2,但是数量却是10 的物品,我们应该把10给拆开,要知道二进制可是能够表示任何数的,所以10 就是可以有1,2, 4,8之内的数把它组成,一开始我们选上 1了,然后让10-1=9,再选上2,9-2=7,在选上 4,7-4=3,

    而这时的3<8了,所以我们就是可以得出 10由 1,2,4,3,来组成,就是这个数量为1,2,3,4的物品了,那么他们的价值是什么呢,是2,4,6,8,也就说给我们的价值为2,数量是10的这批货物,已经转化成了价值分别是2,4,6,8元的货物了,每种只有一件哎!!!!这就是二进制优化的思想。

    那为什么会有完全背包和01 背包的不同使用加判断呢?原因也很简单啊,当数据很大,大于背包的容纳量时,我们就是在这个物品中取上几件就是了,取得量时不知道的,也就理解为无限的啦,这就是完全背包啦,反而小于容纳量的就是转化为01背包来处理就是了,可以大量的省时间。

  • 相关阅读:
    c#构造函数对string类型赋初值
    个人计算机管理
    .net Core2建立MVC网站,部署
    运行或开发.NET Core 的先决条件(支持项目、依赖项)
    在Windows下不使用密码远程登陆Linux
    在Linux下不使用密码远程登陆其他Linux
    如何查看MySQL中每张表占用的空间大小
    pdo如何防止 sql注入
    受教了,memcache比较全面点的介绍,受益匪浅,适用memcached的业务场景有哪些?memcached的cache机制是怎样的?在设计应用时,可以通过Memcached缓存那些内容?
    LVS原理详解及部署之二:LVS原理详解(3种工作方式8种调度算法)
  • 原文地址:https://www.cnblogs.com/iwantstrong/p/5730992.html
Copyright © 2011-2022 走看看