题目链接:
https://vjudge.net/problem/POJ-1742
题目大意:
输入n,m。n为钱的面值种类数,m为一个特定的钱数。
接下来输入n个面值,n个 每个面值的钱币数量,求在不超过m最多能组成多少种面值。
#include<iostream>
#include<stdio.h>
#include<string.h>
#define maxn 100010
using namespace std;
int dp[maxn],sum[maxn];
int price[110],num[110];
int main(){
int n,m;
while(scanf("%d%d",&n,&m)!=EOF&&n+m){
memset(dp,0,sizeof(dp));
int ans=0;
for(int i=1;i<=n;i++)
scanf("%d",&price[i]);
for(int i=1;i<=n;i++)
scanf("%d",&num[i]);
dp[0]=1; //重要。初始化,其意义就是不拿任何面值的钱是可行的
for(int i=1;i<=n;i++){
memset(sum,0,sizeof(sum));
for(int j=price[i];j<=m;j++){
if(!dp[j]&&dp[j-price[i]]&&sum[j-price[i]]<num[i]){ //如果dp[j]没出现过并且dp[j-price[i]]出现过,并且sum[j-price[i]]小于(注意不是小于等于!!!)当前钱币的数量,即现在还有这个面值的钱可以拿
sum[j]=sum[j-price[i]]+1; //当前面值的钱用的次数加1
ans++;
dp[j]=1; //标记j是可行的
}
}
}
printf("%d\n",ans);
}
return 0;
}