题意
有n个硬币,每个硬币面值为a,个数为c,求这些硬币能组成多少种不大于m的和。
题解
对于每个硬币,都从这个硬币的面值开始穷举,一直穷举到m。当总面值为j时,如果尚未凑成过面值j,且凑成过j-weight[i],并且已使用硬币数量use[j-weight[i]]+1小于等于硬币总个数,则代表可以凑成面值j。此时将get[j]标记为1,并将结果ans++。
代码
#include <iostream>
#include<cstdio>
#include<cstring>
#define MAXNUM 100010
using namespace std;
int weight[MAXNUM],cNum[MAXNUM],get[MAXNUM],use[MAXNUM];
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)&&(n+m)){
for(int i=0;i<n;i++){
scanf("%d",&weight[i]);
}
for(int i=0;i<n;i++){
scanf("%d",&cNum[i]);
}
memset(get,0,sizeof(get));
int ans=0;
get[0]=1;
for(int i=0;i<n;i++){
memset(use,0,sizeof(use));
for(int j=weight[i];j<=m;j++){
if(!get[j]&&get[j-weight[i]]&&(use[j-weight[i]]+1)<=cNum[i]){
get[j]=1;
use[j]=use[j-weight[i]]+1;
ans++;
}
}
}
printf("%d\n",ans);
}
return 0;
}