题目
给出n种货币和货币数量,求其能凑出的不超过m的和有多少种。
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
解题思路
一种货币一种货币地进行背包,用last[i]表示到目前这种货币凑出i后还能剩的货币数量,-1表示凑不出来。具体情况看代码。
AC代码
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cctype>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<vector>
#include<algorithm>
using namespace std;
#define LL long long
const int maxn = 1e5+100;
const LL mod = 1e9+7;
const int INF=0x3f3f3f3f;
int n,m;
int a[maxn],c[maxn],last[maxn];
int main()
{
int i,j,k,x,y;
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n==0&&m==0) break;
for(i=1;i<=n;i++) scanf("%d",&a[i]);
for(i=1;i<=n;i++) scanf("%d",&c[i]);
for(i=1;i<=m;i++) last[i]=-1;
for(i=1;i<=n;i++)
{
last[0]=c[i];
for(j=1;j<=m;j++)
{
if(last[j]>=0) last[j]=c[i];
///在用到这种货币之前就已经凑出来了
else if(j>=a[i]&&last[j-a[i]]>=0) last[j]=last[j-a[i]]-1;
///虽然在用到这种货币之前没凑出来,但加一枚货币可以凑出来
}
}
int ans=0;
for(i=1;i<=m;i++)
{
if(last[i]>=0) ans++;
}
printf("%d\n",ans);
}
return 0;
}