时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: G++;GCC;VC;JAVA
一个旅行者有一个最多能装 M公斤的背包,现在有 n件物品,它们的重量分别是W1,W2,…,。
它们的价值分别为C1,C2,…,,求旅行者在不超过背包重量M的情况下,能获得最大总价值。
PS:01背包问题也能用于个人的时间管理,如何分配时间在不同的任务上,才能最大化提升个人价值。
第一行:两个整数,M(背包容量,M<=200)和N(物品数量,N<=30);
第2…N+1行:每行二个整数Wi,Ci,表示每个物品的重量和价值。
一个数,表示最大总价值。
10 4
2 1
3 3
4 5
7 9
12
先定义题目所需的常量
const int MAXN = 201;
int v[MAXN]; // 体积
int w[MAXN]; // 价值
int dp[MAXN][MAXN]; // dp[i][j], j体积下前i个物品的最大价值
我们将所有状态分为两类,第一类不含第 i 件物品,第二类含第 i 件物品,取决于第 i 件物品体积是否大于当前背包所能容纳的大小。例如:当前背包最大容纳量只有5,如果物品体积为7,那么很明显装不进来;注意第二类只有在 v[i] <= j 时才存在。
更多注释可查看下方的完整代码中,有助于理解
#include
using namespace std;
const int MAXN = 201;
int v[MAXN]; // 体积
int w[MAXN]; // 价值
int dp[MAXN][MAXN]; // dp[i][j], j体积下前i个物品的最大价值
/*
10 4
2 1
3 3
4 5
7 9
*/
int main()
{
int i, j, M, N; // M为背包容量,N为物品数量
cin >> M >> N;
for(i = 1; i <= N; i++) {
cin >> v[i] >> w[i];
}
// 初始化0件物品时的各个体积的价值,方便计算
for(i = 0; i <= M; i++) {
dp[0][i] = 0;
}
for(i = 1; i <= N; i++) {
for(j = 1; j <= M; j++) {
// 此时要加入的第i件物品体积如果直接大于 背包当前所能容纳的体积j,那么加入不了,直接取上一个物品相同容纳体积的数据
if(v[i] > j) {
dp[i][j] = dp[i - 1][j];
} else {
// 能装,需进行决策是否选择第i个物品,第二个比较对象为:在减去要新加的物品体积v[i] 基础上,加上新价值看看如何
// 例如:当前容纳体积为 j=5,如果要加入体积为3的物品,那么肯定是在计算体积为2的价值基础上,再加上新的物品价值
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - v[i]] + w[i]);
}
// cout << "i=" << i << " j=" << j << " " << dp[i][j] << endl;
}
}
cout << dp[N][M] << endl;
return 0;
}
对我感兴趣的小伙伴可查看以下链接