HDU2844(多重部分和)
2016-02-25 10:38
423 查看
Coins
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 10961 Accepted Submission(s): 4418
[align=left]Problem Description[/align]
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.
[align=left]Input[/align]
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.
[align=left]Output[/align]
For each test case output the answer on a single line.
[align=left]Sample Input[/align]
3 10
1 2 4 2 1 1
2 5
1 4 2 1
0 0
[align=left]Sample Output[/align]
8
4
该题卡多重背包,数组开的不够大WA,开的太大MLE。
下面是用多重背包做该题的思路。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int A[105],C[105]; int n,m; int dp[100005]; int w[100005]; int used[100005]; int main() { while(scanf("%d%d",&n,&m)!=EOF) { if(!n&&!m) break; memset(dp,0,sizeof(dp)); memset(used,0,sizeof(used)); for(int i=0;i<n;i++) scanf("%d",&A[i]); for(int i=0;i<n;i++) scanf("%d",&C[i]); int cnt=0; for(int i=0;i<n;i++) { int e=1; while(e<C[i]) { w[cnt++]=e*A[i]; C[i]-=e; e<<=1; } if(C[i]>0) w[cnt++]=C[i]*A[i]; } for(int i=0;i<cnt;i++) for(int j=m;j>=w[i];j--) dp[j]=max(dp[j],dp[j-w[i]]+w[i]); int res=0; for(int i=m;i>=1;i--) if(!used[dp[i]]) { used[dp[i]]=1; res++; } printf("%d\n",res); } return 0; }
下面转化为多重部分和问题求解。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int A[105],C[105]; int n,m; int dp[100005]; int main() { while(scanf("%d%d",&n,&m)!=EOF) { if(!n&&!m) break; memset(dp,-1,sizeof(dp)); for(int i=0;i<n;i++) scanf("%d",&A[i]); for(int i=0;i<n;i++) scanf("%d",&C[i]); dp[0]=0; for(int i=0;i<n;i++) for(int j=0;j<=m;j++) if(dp[j]>=0) dp[j]=C[i]; else if(j<A[i]||dp[j-A[i]]<0) dp[j]=-1; else dp[j]=dp[j-A[i]]-1; int res=0; for(int i=1;i<=m;i++) if(dp[i]>=0) res++; printf("%d\n",res); } return 0; }
相关文章推荐
- iOS 设计模式 - 单例模式
- Linux常用命令
- python爬虫获取郑大教务在线成绩数据
- Java分割字符串
- C++11之生产者消费者
- 蒙太奇式的产品设计--老吴说产品
- android测试工具MonkeyRunner--google官网翻译
- 23种设计模式(12):策略模式
- 为本地项目建立版本管理
- 导航栏添加高亮
- Sicily 1321(Dijkstra算法)
- linux下设置SSH服务开机启动
- Parcel: unable to marshal value或Parcel: unable to marshal value null 问题
- mac上的终端bash命令(一) Bourne-Again Shell简介\mac上的终端bash命令(二)基础
- bitbucket添加ssh key
- 【Developer Log】ProGuard扰码web项目(WAR)
- 获取Android正在运行的任务和服务
- Android动画合集之属性动画-初见
- Docker部署JavaWeb项目实战
- Brackets + Sass 学习心得