Description
西尔弗兰的人们使用硬币。他们有价值A 1、A 2、A 3的硬币...一个西尔弗兰的美元。一天,托尼打开他的钱箱,发现里面有一些硬币。他决定在附近的商店买一块非常漂亮的手表。他想支付确切的价格(不找零钱),他知道价格不会超过我。但他不知道手表的确切价格。 你要写一个程序,读n,m,A 1,A 2,A 3...an和C 1,C 2,C 3...C n对应于价值为A 1,A 2,A 3...A n的托尼硬币的数量,然后计算托尼可以用这些硬币支付多少价格(形式1到m)。
Input
输入包含几个测试用例。每个测试用例的第一行包含两个整数n(1 <= n <= 100)、m(m <= 100000)。第二行包含2*N个整数,表示A 1、A 2、A 3…An、C 1、C 2、C 3…C n(1 <= A i <= 100000, 1 <= Ci <= 1000)。最后一个测试用例后面是两个零。
Output
对于每个测试用例,在单行中输出答案。
Sample Input
3 10 1 2 4 2 1 1 2 5 1 4 2 1 0 0
Sample Output
8 4
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 110;
const int M = 100010;
int n, m;
int w[N], s[N];
int f[M]; // 能否拼出总面值是j
int sum[M]; // 总面值大于等于M, 至少需要多少枚硬币
int main() {
while (cin >> n >> m) {
if (n == 0 && m == 0) break;
memset(f, 0, sizeof f);
memset(sum, 0, sizeof sum);
for (int i = 1; i <= n; i ++ ) cin >> w[i];
for (int i = 1; i <= n; i ++ ) cin >> s[i];
int ans = 0;
f[0] = 1;
for (int i = 1; i <= n; i ++ ) {
memset(sum, 0, sizeof sum);
for (int j = w[i]; j <= m; j ++ ) {
if (sum[j - w[i]] < s[i] && f[j] == 0 && f[j - w[i]] == 1) {
f[j] = 1;
sum[j] = sum[j - w[i]] + 1;
ans ++ ;
}
}
}
cout << ans << endl;
}
return 0;
}