POJ1742——Coins 多重背包
2016-03-15 17:57
375 查看
原题如下:
Coins
Description
People in Silverland use coins.They have coins of value A1,A2,A3...An Silverland dollar.One day Tony opened his money-box 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
Sample Output
题目大意:给你n种硬币,每种硬币的面值为Ai,数量分别有Ci个。问你能拼凑出小于等于m的多少种面值。
分析:不难看出是多重背包问题。要优化递推式,记录一下加深印象。
首先,若dp[i+1][j]为用前i种硬币能否拼出价值j的东西。也就是说存在用前i-1种硬币拼成j,j-Ai,j-2*Ai.....j-Ci*Ai的情况。(类似01背包)这样做时间复杂度太高,所以需要优化。经典的优化方式是,不光求出能否拼成,还求出拼成之后剩多少个该面值的硬币。若是不能拼成就记为-1.这样一来,复杂度就是O(nm)了。但是这样做还是不够好。需要空间太大,所以还需要用滚动数组记录结果。
代码如下
#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <cmath>
#include <queue>
#include <ctype.h>
using namespace std;
#define MAXN 100010
#define INF 100000
int dp[MAXN];
int a[110],c[110];
int main()
{
int n,m;
while(scanf("%d%d",&n,&m))
{
if(n==0&&m==0)
break;
for(int i=0;i<n;i++)
cin>>a[i];
for(int i=0;i<n;i++)
cin>>c[i];
memset(dp,-1,sizeof(dp));
int cnt=0;
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;
}
for(int j=1;j<=m;j++)
if(dp[j]>=0)
cnt++;
printf("%d\n",cnt);
}
}
Coins
Time Limit: 3000MS | Memory Limit: 30000K | |
Total Submissions: 32998 | Accepted: 11214 |
People in Silverland use coins.They have coins of value A1,A2,A3...An Silverland dollar.One day Tony opened his money-box 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
题目大意:给你n种硬币,每种硬币的面值为Ai,数量分别有Ci个。问你能拼凑出小于等于m的多少种面值。
分析:不难看出是多重背包问题。要优化递推式,记录一下加深印象。
首先,若dp[i+1][j]为用前i种硬币能否拼出价值j的东西。也就是说存在用前i-1种硬币拼成j,j-Ai,j-2*Ai.....j-Ci*Ai的情况。(类似01背包)这样做时间复杂度太高,所以需要优化。经典的优化方式是,不光求出能否拼成,还求出拼成之后剩多少个该面值的硬币。若是不能拼成就记为-1.这样一来,复杂度就是O(nm)了。但是这样做还是不够好。需要空间太大,所以还需要用滚动数组记录结果。
代码如下
#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <cmath>
#include <queue>
#include <ctype.h>
using namespace std;
#define MAXN 100010
#define INF 100000
int dp[MAXN];
int a[110],c[110];
int main()
{
int n,m;
while(scanf("%d%d",&n,&m))
{
if(n==0&&m==0)
break;
for(int i=0;i<n;i++)
cin>>a[i];
for(int i=0;i<n;i++)
cin>>c[i];
memset(dp,-1,sizeof(dp));
int cnt=0;
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;
}
for(int j=1;j<=m;j++)
if(dp[j]>=0)
cnt++;
printf("%d\n",cnt);
}
}
相关文章推荐
- 使用adb出现cannot parse version string:kg01的解决方法
- Two Sum
- 在项目(新闻内容系统)中,运用百度编辑器内容存入数据库(包括html标签),怎么运用工具来转换成text(不带html标签)!
- redux源码详解
- Android Studio 加载本地Assets中的html文件
- VS轻松开发Node.js应用
- JStorm介绍
- Linux下结束进程的命令
- java如何用正则解析HTML中img标签里图片的路径
- Linux中设置共享目录
- my.cnf
- 接口模板template
- 蓝桥杯 危险系数
- iOSDay08之C语言内存管理
- Oracle 11gR2 RAC ohasd failed to start 解决方法
- linux下如何开启FTP服务器
- linux下 的command not found解决
- 使用throw new Exception 向外层抛异常
- C++:为什么有容器与迭代器
- Spring MVC之二 映射请求