45 lines
2.2 KiB
C++
45 lines
2.2 KiB
C++
#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;
|
||
} |