P1439 背包九讲全集

560 阅读1分钟

背包九讲问题:

1. 01背包问题(一件物品只有选和不选两种模式)             (简单)
2. 完全背包问题(每件物品不限次数)                      (简单)
3. 多重背包问题(物品个数有上限)                        (简单)
4. 混合背包问题                                       (简单)
5. 二维费用的背包问题(背包的限制多了个重量的限制)         (中等)
6. 分组背包问题(每组物品互斥,只能选一件)                (困难)
7. 背包问题求方案数                                    (中等)
8. 求背包问题的方案                                    (中等)
9. 有依赖的背包问题                                    (中等)

1. 01背包问题

截屏2022-04-09 下午6.11.46.png

截屏2022-04-09 下午6.12.11.png 数组的一维按照重量

首先是定义前置变量:

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的最大价值,需要在初始化的时候动点手脚

image.png

2. 完全背包问题

截屏2022-04-12 下午10.32.27.png 每件物品可以重用、分割(价值/重量)

看心情更~

3. 多重背包问题

4. 混合背包问题

5. 二维费用的背包问题

6. 分组背包问题

7. 背包问题求方案数

8. 求背包问题的方案

9. 有依赖的背包问题