Files
python/TangDou/AcWing/BeiBao/11_YiWei_2.cpp
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

45 lines
2.1 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <bits/stdc++.h>
using namespace std;
const int N = 1001;
const int MOD = 1e9 + 7;
const int INF = 0x3f3f3f3f;
int f[N], g[N]; // f[j]、g[j]分别表示体积恰好为j时的最大价值、方案数
int main() {
int n, m;
scanf("%d %d", &n, &m);
// 1、考虑最特殊的f[0],对应的二维表示就是f[0][0],即:在前0个物品中选择,空间恰好是0的情况下。
// f[0]:在前0个物品中选择,空间恰好是0,此时最大值是0,g[0] = 1,即此时方案数是1,什么都不能选,是唯一方案。
f[0] = 0, g[0] = 1;
// 2、再来考虑f[1],f[2],...f[m],对应的二维表示就是f[0][1],f[0][2],f[0][3],...f[0][m],即:在前0个物品中选择,空间恰好是1,2,3,...m的情况下。
// f[1]:在前0个物品中选择,空间恰好是1,此时这是不可能满足条件的。最大值不存在,是不合法状态,同时,因为是预求最大,就设置成最小。f[i]=-INF.相应的,g[i]=0;
for (int i = 1; i <= m; i++) f[i] = -INF, g[i] = 0;
for (int i = 1; i <= n; i++) {
int v, w;
scanf("%d %d", &v, &w);
for (int j = m; j >= v; j--) {
int s = 0;
int t = max(f[j], f[j - v] + w);
if (t == f[j])
s = (s + g[j]) % MOD; //添加不更新的方案
if (t == f[j - v] + w)
s = (s + g[j - v]) % MOD; //添加更新的方案
f[j] = t;
g[j] = s;
}
}
//由于定义的状态表示是“空间恰好是i”,那么最大值的产生,可不一定存储在“空间恰好是m”的状态下,m及以下的各个状态,都可能装着最大值,
//我们遍历一次f数组,找出最大值,然后二次遍历f数组、g数组,累加可以获得最大值时的方案数量。
int mx = 0, res = 0;
for (int i = 0; i <= m; i++) mx = max(mx, f[i]); //获取最大价值
for (int i = 0; i <= m; i++)
if (mx == f[i]) res = (res + g[i]) % MOD; //等于最大价值的方案都添加
printf("%d\n", res);
return 0;
}