最新文章
这里会显示最新的几篇文章摘要。
记录生活,分享知识,与你一起成长。
这里会显示最新的几篇文章摘要。
有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。
第 i 件物品的体积是 vi,价值是 wi。
求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
输出 最优选法的方案数。注意答案可能很大,请输出答案模 10+7的结果。
第一行两个整数,N,V,用空格隔开,分别表示物品数量和背包容积。
接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 件物品的体积和价值。
数据范围
0<N,V≤1000
0<vi,wi≤1000
输出一个整数,表示 方案数 模 10+7 的结果。
4 5
1 2
2 4
3 4
4 6
2
求解最优方案的方案数,我们需要维护两个数组,一个数组记录最大价值,一个数组记录方案数,对于方案数的状态,不选物品i的状态是```cpp
if(dp[i][j] == dp[i-1][j]) g[i][j] += g[i-1][j]
选择物品`i`的状态是
```cpp
if(j >= v[i] && dp[i][j] == dp[i-1][j-v[i]]) g[i][j] += g[i-1][j]
方案总数是两种状态方案的和,因为可能出现选择和不选物品i的价值是一样的情况,所以使用的是+=
const int N = 1e9 + 7;
int v[1005],w[1005];
int dp[1005][1005],g[1005][1005];
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
//
// freopen("E:/Code/C++/untitled1/input.txt","r",stdin);
// freopen("output.txt","w",stdout);
int n,vol;
cin >> n >> vol;
f(i,1,n+1) cin >> v[i] >> w[i];
g[0][0] = 1; // 初始化方案
for(int i = 1;i <= n;++i)
for(int j = 0;j <= vol;++j)
{
if(j>= v[i]) dp[i][j] = max(dp[i-1][j],dp[i-1][j-v[i]] + w[i]);
else dp[i][j] = dp[i-1][j];
if(dp[i][j] == dp[i-1][j]) g[i][j] = g[i-1][j] % N;
if(j >= v[i] && dp[i][j] == dp[i-1][j-v[i]] + w[i])
g[i][j] = (g[i-1][j-v[i]]%N + g[i][j]%N)%N;
}
cout << g[n][vol]%N;
}