本题解,由yxc视频讲解改编。
// 视频中的方法,略有改动。
// 初始化时: f[0] = 0, 其余为-1
// f[i]表示volume恰好是i时的最值。
const int N = 1001, MOD = 1e9 + 7;
int n, V;
int v[N], w[N];
int f[N], cnt[N];
int knapsack() {
// f[0] = 0;
fill(f + 1, f + V, -1);
cnt[0] = 1;
for (int i = 0; i < n; i++) {
for (int j = V; j >= v[i]; j--) {
if (f[j - v[i]] + w[i] > f[j]) {
cnt[j] = cnt[j - v[i]];
} else if (f[j] == f[j - v[i]] + w[i]) {
cnt[j] += cnt[j - v[i]];
cnt[j] %= MOD;
}
f[j] = max(f[j], f[j - v[i]] + w[i]);
}
}
int maxw = *max_element(f, f + V + 1);
int res = 0;
for (int i = 0; i <= V; i++) {
if (f[i] == maxw) {
res += cnt[i];
res %= MOD;
}
}
return res;
}
int main() {
cin >> n >> V;
for (int i = 0; i < n; i++) {
cin >> v[i] >> w[i];
}
cout << knapsack();
return 0;
}
也可像其他背包题一样,初始化全为0。代码会短一点。
// 初始化时: f[i]全为0。
// f[i]表示volume up to i时的最值。
int knapsack() {
fill(cnt, cnt + n, 1);
for (int i = 0; i < n; i++) {
for (int j = V; j >= v[i]; j--) {
if (f[j] < f[j - v[i]] + w[i]) {
cnt[j] = cnt[j - v[i]];
} else if (f[j] == f[j - v[i]] + w[i]) {
cnt[j] += cnt[j - v[i]];
cnt[j] %= MOD;
}
f[j] = max(f[j], f[j - v[i]] + w[i]);
}
}
return cnt[V];
}