原题:

题目分析:具有重叠子问题和最优解结构,所以采取动态规划:
状态:
dp[i][j]表示在1 ~ i 件物品中,j的体积所得到的最优解(最大的价值);
初始化:
在只有一件物品的时候:
1> 如果该物品的体积小于等于当前给的定体积时候,就选中该物品dp[1][j] = w[j];
else if (v[i] > j)dp[i][j] = dp[i - 1][j];
2> 如果该物品的体积大于当前给定的体积的时候,就不选该物品dp[1][j] = 0;
如果当前物体的体积(v[i])于当前给定的体积(j)的时候:
一定不选这个物品:dp[i][j] = dp[i - 1][j];
if (i == 1) { // 一件物品
if (v[i] <= j)dp[i][j] = w[i];
else dp[i][j] = 0;
}
状态转移方程:
dp[i][j] = max(dp[i -1][j],dp[i - 1][j - v[i]] + w[i])
o1背包问题主要关注物品的选与不选,其中:
dp[i - 1][j]:表示不选地i件物品,在j的体积下,在前i- 1件物品中选择;
dp[i - 1[j - v[i]] + w[i]:表示选择第i件物品,在去除i 所占的体积后(j - v[i]),在 i- 1件物品中选择;
max:在选与不选中选择价值最大的哪一种选择作为dp[i][j]的最优解;
最优解
**dp[N][V]**在1 ~ N的物品中,给定体积为V时可以选择的最大价值;
完整代码:
#include<iostream>
#include<algorithm>
using namespace std;
int v[1000000];
int w[1000000];
int dp[10000][10000]; // 状态
int main() {
int N, V;
cin >> N >> V;
for (int i = 1; i <= N; i++) {
cin >> v[i] >> w[i];
}
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= V; j++) {
if (i == 1) { //初始化
if (v[i] <= j)dp[i][j] = w[i]; // 选择当前的一个物品
else dp[i][j] = 0; // 不选择当前的一个物品
}
else if (v[i] > j)dp[i][j] = dp[i - 1][j];// 当前的物品体积大于当前给定的体积,不选择
else {
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - v[i]] + w[i]);
// 状态转移方程:选择该物品和不选择该物品相比较,选择价值最大的一个作为dp[i][j]
}
}
}
cout << dp[N][V] << endl;
}
6500

被折叠的 条评论
为什么被折叠?



