1820: 【基础】背包问题求方案数
内存限制:128 MB
时间限制:1.000 S
评测方式:文本比较
命题人:
提交:3
解决:2
题目描述
有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。
第 i 件物品的体积是 vi,价值是 wi。
求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
第 i 件物品的体积是 vi,价值是 wi。
求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
输出 最优选法的方案数。注意答案可能很大,请输出答案模 109+7的结果。
输入
第一行两个整数,N,V,用空格隔开,分别表示物品数量和背包容积。
接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 件物品的体积和价值。
数据范围
0<N,V≤1000
0<vi,wi≤1000
接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 件物品的体积和价值。
数据范围
0<N,V≤1000
0<vi,wi≤1000
输出
输出一个整数,表示 方案数 模 109+7 的结果。
样例输入 复制
4 5
1 2
2 4
3 4
4 6
样例输出 复制
2
提示
#include <iostream>
#include <algorithm>
using namespace std;
const int MOD = 1000000007;
const int MAXN = 1005;
const int MAXV = 1005;
int dp[MAXN][MAXV];
int cnt[MAXN][MAXV];
int main()
{
int n, vol;
cin >> n >> vol;
for(int j = 0; j <= vol; j++)
{
dp[0][j] = 0;
cnt[0][j] = 0;
}
cnt[0][0] = 1;
for(int i = 1; i <= n; i++)
{
int v,w;
cin >> v >> w;
for(int j = 0; j <= vol; j++)
{
dp[i][j] = dp[i-1][j];
cnt[i][j] = cnt[i-1][j];
if(j >= v)
{
int nv = dp[i-1][j-v] + w;
if(nv > dp[i][j])
{
dp[i][j] = nv;
cnt[i][j] = cnt[i-1][j-v];
}
else if(nv == dp[i][j])
{
cnt[i][j] = (cnt[i][j] + cnt[i-1][j-v]) % MOD;
}
}
}
}
int maxVal = 0;
for(int j = 0; j <= vol; j++) maxVal = max(maxVal, dp[n][j]);
int ans = 0;
for(int j = 0; j <= vol; j++)
{
if(dp[n][j]==maxVal) ans=(ans+cnt[n][j])%MOD;
}
cout << ans << endl;
return 0;
}
#include <iostream>
#include <algorithm>
using namespace std;
const int MOD = 1000000007;
const int MAXV = 1005;
int dp[MAXV];
int cnt[MAXV];
int main()
{
int N, V;
cin >> N >> V;
for(int j = 0; j <= V; j++)
{
dp[j] = 0;
cnt[j] = 0;
}
cnt[0] = 1;
for(int i = 1; i <= N; i++)
{
int v, w;
cin >> v >> w;
for(int j = V; j >= v; j--)
{
int new_val = dp[j - v] + w;
if(new_val > dp[j])
{
dp[j] = new_val;
cnt[j] = cnt[j - v];
}
else if(new_val == dp[j])
{
cnt[j] = (cnt[j] + cnt[j - v]) % MOD;
}
}
}
int maxVal = 0;
for(int j = 0; j <= V; j++)
{
maxVal = max(maxVal, dp[j]);
}
int ans = 0;
for(int j = 0; j <= V; j++)
{
if(dp[j] == maxVal)
{
ans = (ans + cnt[j]) % MOD;
}
}
cout << ans << endl;
return 0;
}