背包问题
主要讲三个背包:
01 背包,完全背包,多重背包。
主要讲四个背包:
01 背包,完全背包,多重背包,混合背包。
01 背包
01背包的意思是选一个或者不选。
朴素版:
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1111;
int v[N]; //v[i]表示i个物品的价值
int w[N]; //w[i]表示第i个物品的重量
int f[N][N]; //f[i][j]表示在容量为j的情况下,选i个物品的最大值
int n, m;
int main(){
cin >> n >> m;
for(int i = 1;i <= n ;i++)cin >> v[i] >> w[i];
//数据输入
for(int i = 1;i <= n;i++)
for(int j = 0;j <= m;j++){
f[i][j] = f[i - 1][j]; //如果不选的话,前面的状态要推到后面去。
if(j>=v[i])
f[i][j] = max(f[i][j], f[i - 1][j - v[i]] + w[i]);
}
//f[i][j]的最大值,是前一个状态推出来,选第i个物品或者不选
//不选的话,f[i][j] = f[i - 1][j]
//选的话,f[i][j] = f[i-1][j - w[i]] + v[i],前一个状态(i-1) + 第i件物品
//容量至少需要w[i],加上以后会减少w[i]的容量,所以需要减去这部分的重量,再加上v[i]的价值。
cout << f[n][m]<<endl;
return 0;
}
优化:
这里我们可以发现,其实每次最多只用到了f [ i ]的前一个状态f[ i -1 ],那么其实有些是不需要的额,我们可以用滚动数组解决。
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1111;
int v[N], w[N], f[N];
int n, m;
int main(){
cin >> n >> m;
for(int i = 1;i <= n ;i++)cin >> v[i] >> w[i