0-1背包问题与完全背包问题
重点参考资料:背包问题九讲2.0
0-1背包问题
#include <iostream>
using namespace std;
const int MAX_N = 1001;
int N, V;
int v[MAX_N], w[MAX_N];
//int dp[MAX_N][MAX_N]; // 堆空间,默认初始化0
int dp[MAX_N];
int main(int argc, char* argv[])
{
cin >> N >> V;
for (int i = 1; i <= N; i++) {
cin >> v[i] >> w[i];
}
// 二维动态规划 dp[i][j]:下标1到i之间体积为j的最大价值
// 初始化第一行
//for(int j = v[0]; j <= V; j++) {
// dp[0][j] = w[0];
//}
/*
for (int i = 1; i <= N; i++) { // 物品
for (int j = 0; j <= V; j++) { // 体积
dp[i][j] = dp[i - 1][j];
if(j - v[i] >= 0) {
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - v[i]] + w[i]);
}
}
}
cout << dp[N][V] << endl;
*/
// 简化,压缩空间。就是那个二维的表格,现在没有行信息了,只有列信息,列信息从后往前更新(因为用的是上一行的信息)
for (int i = 1; i <= N; i++) {
for (int j = V; j >= v[i]; j--) {
dp[j] = max(dp[j], (dp[j - v[i]] + w[i]));
}
}
cout << dp[V] << endl;
return 0;
}
完全背包问题
#include <iostream>
using namespace std;
const int MAX_N = 1001;
int N, V;
int v[MAX_N], w[MAX_N];
//int dp[MAX_N][MAX_N]; // 堆空间,默认初始化0
int dp[MAX_N];
int main(int argc, char* argv[])
{
cin >> N >> V;
for (int i = 1; i <= N; i++) {
cin >> v[i] >> w[i];
}
// 二维动态规划 dp[i][j]:下标1到i之间体积为j的最大价值
// 初始化第一行
//for(int j = v[0]; j <= V; j++) {
// dp[0][j] = w[0];
//}
/*
for (int i = 1; i <= N; i++) { // 物品
for (int j = 0; j <= V; j++) { // 体积
dp[i][j] = dp[i - 1][j];
if(j - v[i] >= 0) {
dp[i][j] = max(dp[i - 1][j], dp[i][j - v[i]] + w[i]);
}
}
}
cout << dp[N][V] << endl;*/
// 简化,压缩空间。就是那个二维的表格,现在没有行信息了,只有列信息,列信息从前往后更新
for (int i = 1; i <= N; i++) {
for (int j = v[i]; j <= V ; j++) {
dp[j] = max(dp[j], (dp[j - v[i]] + w[i]));
}
}
cout << dp[V] << endl;
return 0;
}
总结:
两层循环,可以用二维数组,也可以用一维数组压缩空间
- 0-1背包每个东西最多选择一次,完全背包每个东西可以无限次选择
- 0-1背包的内循环是从大到小更新,完全背包内循环是从小到大更新