You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

45 lines
2.2 KiB

2 years ago
#include <bits/stdc++.h>
using namespace std;
const int N = 1010, MOD = 1e9 + 7;
int f[N][N], g[N][N]; // f[j]、g[j]分别表示体积最大为j时的最大价值、方案数
int main() {
int n, m;
scanf("%d %d", &n, &m);
// 初始化,两个二维表,第一列比较特殊,可以进行初始化
// f[0][0],g[0][0]
// 在前0个物品中选择空间最多为0只能什么也不选择最大值f[0][0]=0,方案数g[0][0]=1
f[0][0] = 0, g[0][0] = 1;
// f[0][1~m],g[0][1~m]
// 在前0个物品中选择空间最多为1~m,最大值肯定是0因为没的选择嘛对应的方案数也是1
for (int i = 1; i <= m; i++) f[0][i] = 0, g[0][i] = 1;
// 从第二列开始吧
for (int i = 1; i <= n; i++) { // 枚举每个物品,理解为阶段
int v, w;
scanf("%d %d", &v, &w);
for (int j = 0; j <= m; j++) { // 枚举当前阶段可能的剩余体积
int val = f[i - 1][j]; // 在没选择当前物品前的最大价值
if (j >= v) { // 如果剩余体积可以装得下第i个阶段的物品,选择与否可能会影响最大价值
if (val > f[i - 1][j - v] + w) { // 如果选择了当前物品还不如不选
f[i][j] = val; // 那还是用原来的最大价值吧
g[i][j] = g[i - 1][j]; // 个数也随着迁移吧
} else if (val == f[i - 1][j - v] + w) { // 如果一样的价值呢?那就需要累加了
f[i][j] = val;
g[i][j] = (g[i - 1][j] + g[i - 1][j - v]) % MOD;
} else { // 如果可以理新呢?
f[i][j] = f[i - 1][j - v] + w; // 更新最大值
g[i][j] = g[i - 1][j - v]; // 同步更新方案数量
}
} else { // 如果装不上,只能继承
f[i][j] = val;
g[i][j] = g[i - 1][j];
}
}
}
printf("%d\n", g[n][m]);
return 0;
}