题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=2844
Coins
问题描述
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\n",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\n",ans); } return 0; } //end-----------------------------------------------------------------------
来源:https://www.cnblogs.com/fenice/p/5917304.html