zoukankan      html  css  js  c++  java
  • Coins(多重背包+二进制优化)

    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
    还有R和U的总结就不写了;总结基本都包括在下面了;
    题意:给你n种硬币的数量和价值,让你求组成小于等于m钱数的组成方案数;
    解题思路:第一遍写超时了,本来想不写了的,赶紧写ACM-steps,过了好长时间上课老师讲了二进制优化才,才有了思路,这里需要解释一下二进制优化:任何一个数都可以用二进制数+非二进制数来表示,比如10可以表示为1+2+4+3;利用这一个原理将双重循环的背包转化为单重循环的01背包问题,这样可以大大的节省时间;在状态转移的过程中需要做一个判断,当前钱的总价值是不是超过要求钱数,超过了,就是一个完全背包问题,没超过就可以转化为01背包问题;dp[i]表示不超过i钱数的能凑出来最大钱数,最后只要dp[i]==i;就是一种方案;
    感悟:背包问题需要时间来理解。时间越长有的东西理解的越深刻啊;
    代码:
    #include
    #define N 20010
    using namespace std;
    int v[N],dp[N*100],w[N],n,m;
    void zero_onebag(int v)//01背包
    {
        for(int i=m;i>=v;i--)
            dp[i]=max(dp[i],dp[i-v]+v);
    }
    void complet_bag(int v)//完全背包
    {
        for(int i=v;i<=m;i++)
            dp[i]=max(dp[i],dp[i-v]+v);
    }
    void multiply_bag(int v,int k)//多重背包
    {
        if(k*v>=m)
        {
            complet_bag(v);
            return ;
        }
        int d=1;
        while(d
        {
            zero_onebag(d*v);
                k-=d;
            d<<=1;
        }
        zero_onebag(k*v);
    }
    int main()
    {
        //freopen("in.txt", "r", stdin);
        while(scanf("%d %d",&n,&m)!=EOF)
        {
            if(n==0&&m==0)
                break;
            //cout<<n<<" "<<m<<endl;
            for(int i=0;i
                scanf("%d",&v[i]);
            for(int i=0;i
                scanf("%d",&w[i]);
            memset(dp,0,sizeof dp);
            for(int i=0;i
                multiply_bag(v[i],w[i]);
            int ans=0;
            //for(int i=1;i<=m;i++)
            //    cout<<dp[i]<<" ";
            //cout<<endl;
            for(int i=1;i<=m;i++)
                if(dp[i]==i)
                ans++;
            printf("%d ",ans);
        }
        return 0;
    }
  • 相关阅读:
    常量的定义
    二进制、八进制、十进制、十六进制间的转换
    使用简单的 5 个步骤设置 Web 服务器集群
    新手推荐:IIS+PHP+MYSQL环境配置教程
    windows7 iis安装与配置
    web服务器配置方法
    如何配置web服务器
    系统没有“internet信息服务(IIS)管理器”
    Html 内嵌 选择器属性 Dom操作 JavaScript 事件
    <转载>使用css让大图片不超过网页宽度
  • 原文地址:https://www.cnblogs.com/wuwangchuxin0924/p/5781538.html
Copyright © 2011-2022 走看看