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.
|
|
|
|
#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;
|
|
|
|
|
}
|