zoukankan      html  css  js  c++  java
  • HDU 2844 Coins 多重背包

    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=2844

    Coins

    Time Limit: 2000/1000 MS (Java/Others)
    Memory Limit: 32768/32768 K (Java/Others)
    #### 问题描述 > 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.

    输入

    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.

    输出

    For each test case output the answer on a single line.

    样例输入

    3 10
    1 2 4 2 1 1
    2 5
    1 4 2 1
    0 0

    样例输出

    8
    4

    题解

    裸的多重背包,这里提供两种思路:
    1、开个cntv数组维护一下第i个背包用了几次,限制一些非法的转移,像完全背包那一做一遍就ok。

    #include<map>
    #include<set>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<ctime>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<bitset>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<functional>
    #include<sstream>
    using namespace std;
    #define X first
    #define Y second
    #define mkp make_pair
    #define lson (o<<1)
    #define rson ((o<<1)|1)
    #define mid (l+(r-l)/2)
    #define sz() size()
    #define pb(v) push_back(v)
    #define all(o) (o).begin(),(o).end()
    #define clr(a,v) memset(a,v,sizeof(a))
    #define bug(a) cout<<#a<<" = "<<a<<endl
    #define rep(i,a,b) for(int i=a;i<(b);i++)
    #define scf scanf
    #define prf printf
    
    typedef long long LL;
    typedef vector<int> VI;
    typedef pair<int,int> PII;
    typedef vector<pair<int,int> > VPII;
    
    const int INF=0x3f3f3f3f;
    const LL INFL=0x3f3f3f3f3f3f3f3fLL;
    const double eps=1e-8;
    const double PI = acos(-1.0);
    
    //start----------------------------------------------------------------------
    
    const int maxn=101010;
    
    int cntv[maxn];
    bool dp[maxn];
    int v[maxn],c[maxn];
    
    int main() {
        int n,m;
        while(scf("%d%d",&n,&m)==2&&n){
            clr(dp,0);
            for(int i=1;i<=n;i++) scf("%d",&v[i]);
            for(int i=1;i<=n;i++) scf("%d",&c[i]);
    
            clr(dp,0);
            dp[0]=1;
    
            for(int i=1;i<=n;i++){
                clr(cntv,0);
                for(int j=v[i];j<=m;j++){
                    if(!dp[j]&&dp[j-v[i]]&&cntv[j-v[i]]<c[i]){
                        dp[j]=1;
                        cntv[j]=cntv[j-v[i]]+1;
                    }
                }
            }
    
            int ans=0;
            for(int i=1;i<=m;i++) ans+=dp[i];
    
            prf("%d
    ",ans);
        }
    
        return 0;
    }
    
    //end-----------------------------------------------------------------------
    

    2、用二进制拆分转化成01背包。

    #include<map>
    #include<set>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<ctime>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<bitset>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<functional>
    #include<sstream>
    using namespace std;
    #define X first
    #define Y second
    #define mkp make_pair
    #define lson (o<<1)
    #define rson ((o<<1)|1)
    #define mid (l+(r-l)/2)
    #define sz() size()
    #define pb(v) push_back(v)
    #define all(o) (o).begin(),(o).end()
    #define clr(a,v) memset(a,v,sizeof(a))
    #define bug(a) cout<<#a<<" = "<<a<<endl
    #define rep(i,a,b) for(int i=a;i<(b);i++)
    #define scf scanf
    #define prf printf
    
    typedef long long LL;
    typedef vector<int> VI;
    typedef pair<int,int> PII;
    typedef vector<pair<int,int> > VPII;
    
    const int INF=0x3f3f3f3f;
    const LL INFL=0x3f3f3f3f3f3f3f3fLL;
    const double eps=1e-8;
    const double PI = acos(-1.0);
    
    //start----------------------------------------------------------------------
    
    const int maxn=101010;
    
    int cntv[maxn];
    bool dp[maxn];
    int v[maxn],c[maxn];
    
    int main() {
        int n,m;
        while(scf("%d%d",&n,&m)==2&&n){
            clr(dp,0);
            for(int i=1;i<=n;i++) scf("%d",&v[i]);
            for(int i=1;i<=n;i++) scf("%d",&c[i]);
    
            VI arr;
            for(int i=1;i<=n;i++){
                int j=1;
                //二进制拆分
                while(c[i]>0){
                    if(c[i]>=j){
                        arr.pb(v[i]*j);
                        c[i]-=j;
                    }else{
                        arr.pb(v[i]*c[i]);
                        c[i]=0;
                    }
                    j<<=1;
                }
            }
    
            clr(dp,0);
            dp[0]=1;
    
            for(int i=0;i<arr.sz();i++){
                for(int j=m;j>=arr[i];j--){
                    dp[j]=dp[j]|dp[j-arr[i]];
                }
            }
    
            int ans=0;
            for(int i=1;i<=m;i++) ans+=dp[i];
    
            prf("%d
    ",ans);
        }
    
        return 0;
    }
    
    //end-----------------------------------------------------------------------
  • 相关阅读:
    有关 JavaScript 的 10 件让人费解的事情
    Apache ab介绍1
    Oracle Raw,number,varchar2... 转换
    Flex开发者需要知道的10件事
    linux命令之nice
    JavaIO复习和目录文件的复制
    使用php获取网页内容
    linux 安装sysstat使用iostat、mpstat、sar、sa
    SQL Injection 实战某基金
    ubuntu root锁屏工具
  • 原文地址:https://www.cnblogs.com/fenice/p/5917304.html
Copyright © 2011-2022 走看看