Coins
Time Limit: 3000MS | Memory Limit: 30000K | |
Total Submissions: 29601 | Accepted: 10031 |
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.
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个价值为a1,a2....an的硬币,每种硬币的数目分别为c1,c2....cn。求用这些硬币能恰好支付的1-m的价格有多少种?
题解:本问题是个多重背包问题,用多重背包O(NV)的解法可做。其实这题还有更简单的方法,复杂度为O(VN)。
用dp[i][j] 表示前i种硬币恰好支付价值j后,第i种硬币最多剩多少个?
初始化dp初值为-1,表示前i种硬币不能恰好支付价格j。
转移就是:
if(dp[i-1][j]>=0)//不用第i种硬币
dp[i][j]=c[i];
else if(j-a[i]>=0&&dp[i][j-a[i]]>0)//用第i种硬币
dp[i][j]=dp[i][j-a[i]]-1;
代码如下:
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<stdlib.h>
#include<vector>
#define inff 0x3fffffff
#define nn 110000
#define mod 1000000007
typedef long long LL;
const LL inf64=inff*(LL)inff;
using namespace std;
int n,m;
int a[nn],c[nn];
int dp[2][nn];
int main()
{
int i,j;
while(scanf("%d%d",&n,&m)&&(n+m))
{
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(i=1;i<=n;i++)
{
scanf("%d",&c[i]);
}
memset(dp,-1,sizeof(dp));
dp[0][0]=0;
int t=1;
for(i=1;i<=n;i++)
{
for(j=0;j<=m;j++)
{
if(dp[1-t][j]>=0)
dp[t][j]=c[i];
else if(j-a[i]>=0&&dp[t][j-a[i]]>0)
dp[t][j]=dp[t][j-a[i]]-1;
}
t=1-t;
for(j=0;j<=m;j++)
{
dp[t][j]=-1;
}
}
int ans=0;
for(j=1;j<=m;j++)
{
if(dp[1-t][j]>=0)
ans++;
}
printf("%d\n",ans);
}
return 0;
}