- 第一时间:我是不是做过?
细想一下,好像真没做过。
但是知识 是互通的!- 仔细分析一下,发现是多重背包方案(理论上还是多重背包)
于是果断写了个朴素多重背包,毫不意外地WA了.
最后写下二进制优化版,成功AC.- 哦对了,这里的“二进制”,是,但不完全是。
它是利用了二进制的思想,将一个数按照1, 2, 4…2n,n( n 不足 2n+1 ),
来拆开成 log2(n) + 1 个物品
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 1e5 + 10;
bool f[N];
int n, m, w[N], s, cnt;
void init() {
memset(f, 0, sizeof f);
f[0] = 1;
cnt = 0;
}
int main() {
while (~scanf("%d%d", &n, &m)) {
if (!n && !m)
break;
init();
for (int i = 1; i <= n; i++) scanf("%d", &w[i]);
for (int i = 1; i <= n; i++) {
scanf("%d", &s);
int k = 1;
while (k <= s) {
for (int j = m; j >= w[i] * k; j--)
if (f[j - w[i] * k] && !f[j])
f[j] = 1, cnt++;
s -= k;
k *= 2;
}
if (s)
for (int j = m; j >= w[i] * s; j--)
if (f[j - w[i] * s] && !f[j])
f[j] = 1, cnt++;
}
printf("%d\n", cnt);
}
return 0;
}