C - Coins
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
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.
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 0Sample Output
8 4
当a[i]=2时,我要凑金额为4的钱数,当金额为3时,需要用到1个面值为2和1个面值为1的,当要凑面值为4的时候,就需要两个面值为2的,面值为2只有一个,并且已经被金额为3的占用,所以金额为4的就凑不成(num[2]>1 num[2]表示面值为2的使用的次数,超过题目给定的个数,所以凑不成)
背包 参考网址 ::::
https://blog.csdn.net/qq_38749759/article/details/77406397
https://www.cnblogs.com/xinsheng/archive/2013/12/04/3458362.html
https://blog.csdn.net/flyinghearts/article/details/5898183
https://blog.csdn.net/lxy767087094/article/details/54730613
https://blog.csdn.net/jerans/article/details/54916955
https://www.cnblogs.com/A-S-KirigiriKyoko/p/6036368.html
https://blog.csdn.net/na_beginning/article/details/62884939
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<stdlib.h>
using namespace std;
int dp[100005];
int a[1000],c[1000];
int num[100005];
int main(){
int n,m,i,j;
while(scanf("%d %d",&n,&m)!=EOF && n&&m)
{
for(i=0;i<n;i++){
scanf("%d",&a[i]);
}
for(i=0;i<n;i++){
scanf("%d",&c[i]);
}
for(i=1;i<=m;i++){
dp[i]=0;
}
dp[0]=1;
int cnt=0;
for(i=0;i<n;i++){
for(j=0;j<=m;j++)
num[j]=0;
for(j=a[i];j<=m;j++){
if(!dp[j] && dp[j-a[i]] && num[j-a[i]]<c[i]){ //使用钱a[i]来凑钱j
//用金额a[i]凑金额j,如果不能正好凑成的话,j-a[i]就是为了凑金额j还所需要的金额
//num数组中,j代表我当前要拼凑的金额,a[i]代表的要用掉的金额,j-a[i]表示要凑金额为j的钱还需要用到的钱,
num[j]=num[j-a[i]]+1;
//num数组用来记录用的钱的个数,假设我要凑金额为3(j=3),我要用到金额为2的钱还要用到金额为1的钱,num数组记录金额钱数的使用次数
//如果大于给定的纸张的个数,就不能再凑,钱的数量不够用了。
dp[j]=1;//当前面值为j的金额已经拼凑出来了,就把这个金额标记
cnt++;//凑出来一种,cnt就加1,来记录凑出的种类个数
}
}
}
printf("%d\n",cnt);
}
return 0;
}