背包九讲问题:
1. 01背包问题(一件物品只有选和不选两种模式) (简单)
2. 完全背包问题(每件物品不限次数) (简单)
3. 多重背包问题(物品个数有上限) (简单)
4. 混合背包问题 (简单)
5. 二维费用的背包问题(背包的限制多了个重量的限制) (中等)
6. 分组背包问题(每组物品互斥,只能选一件) (困难)
7. 背包问题求方案数 (中等)
8. 求背包问题的方案 (中等)
9. 有依赖的背包问题 (中等)
1. 01背包问题
数组的一维按照重量
首先是定义前置变量:
const int N = 50;
int n,m;//数量,箱子的容积
int f[N][N];//每个物品
int v[N],w[N];//每个物品的价值和重量
然后
for(int i = 1; i <= n;i++)
for(int j = 0; j<= m; j++){
//注意这里的i-1超不超范围
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]);
}
最后是输出答案中最大的那个
int res = 0;
for(int i = 0; i <=m; i++ ) res = max (res, f[n][i]);
坑的是oj那个要多组输入......不然wa
这里有可以优化的地方: 即将二维数组优化为一维数组,通过质量做索引,最后选择f[m](这个也是值得考究的)
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 50;
int n,m;//数量,箱子的容积
int f[N];//每个物品
int v[N],w[N];//每个物品的体积和
int main(){
cin >> m >> n;
for(int i = 1; i <= n;i++) cin >> v[i] >> w[i];
for(int i = 1; i <= n;i++)
for(int j = m; j >= v[i]; j--){
f[j] = max(f[j], f[j - v[i]] + w[i]);
}
cout<<f[m]<<endl;
return 0;
}
若想获得就是这个m的最大价值,需要在初始化的时候动点手脚
2. 完全背包问题
每件物品可以重用、分割(价值/重量)
看心情更~