大部分内容来自:https://tangshusen.me/2019/11/24/knapsack-problem/
1. 01背包
二维数组+动规
状态转移方程:
定义f[i][j]: 前i个物品,背包容量j下的最优解1)当前背包容量不够,为前i-1个物品最优解:j<w[i]: f[i][j] = f[i-1][j]
2)当前背包容量够,判断选与不选第i个物品
选:f[i][j] = f[i-1][j-w[i]] + v[i]
不选:f[i][j] = f[i-1][j]
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1005;
int w[MAXN]; // 重量
int v[MAXN]; // 价值
int f[MAXN][MAXN]; // f[i][j], j重量下前i个物品的最大价值
int main()
{
int n, m;
cin >> n >> m;
for(int i = 1; i <= n; ++i)
cin >> w[i] >> v[i];
for(int i = 1; i <= n; ++i)
for(int j = 1; j<=m; ++j)
{
// 当前重量装不进,价值等于前i-1个物品
if(j<w[i])
f[i][j] = f[i-1][j];
// 能装,需判断
else
f[i][j] = max(f[i-1][j], f[i-1][j-w[i]]+v[i]);
}
return 0;
}
f[i]的状态之和i-1有关,f[i]表示为体积为i的情况下,最大价值是多少。
优化(动规+一维数组)
状态转移方程为:f[j]=max(f[j],f[j-w[i]]+v[i])
for(int i = 1; i <= n; ++i)
{
for(int j = m; j>=0; --j)
if(j>=w[i])
f[j] = max(f[j], f[j-w[i]]+v[i]);
}
return f[m]