[toc]
说明:
本文所讲内容摘录自崔添翼:背包九讲,并对其中的数学内容和一些较为复杂的内容进行了删减,增加了基础的例题,只是面向初学者或者不需要深入理解背包及其衍生问题的读者,如果有能力并且有意愿加深理解,本文可能会对您形成误导,请移步崔添翼:背包九讲.
混合背包问题
混合背包问题有:
- 01背包和完全背包混合
- 01背包、完全背包、多重背包的混合
题目解法
只需要将问题简单的糅合在一起就可以解决问题,解决这一类问题的套路是:
- 最外层循环
i
遍历物品的种类 - 第二层循环遍
j
历背包的容量- 当物品的数量只有一个时(01背包问题):使用01背包的转移方程
- 当物品的数量有无限多个时(完全背包问题):需要加一个循环遍历选择物品
i
的数量 - 当物品的数量有
m
个时:(多重背包问题) 同完全背包问题,需要加一个循环遍历选择物品i
的数量 - 注意:以上三种条件是相互独立的,也就是三个
if
分支
伪代码如下:
1 | for i ← 1 to N |
01背包的转移方程
1 | for (int i = 1; i <= N; i++) { |
完全背包的转移方程
1 | for (int i = 1; i <= N; i++) { |
多重背包的转移方程
1 | for (int i = 1; i <= N; i++) { |
相关题目练习
题目URL
有 N
种物品和一个容量是 V
的背包。
物品一共有三类:
- 第一类物品只能用1次(01背包);
- 第二类物品可以用无限次(完全背包);
- 第三类物品最多只能用 $s_i$ 次(多重背包);
每种体积是 $v_i$,价值是 $w_i$。
求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大。
输出最大价值。
输入格式
第一行两个整数,N
,V
,用空格隔开,分别表示物品种数和背包容积。
接下来有 N
行,每行三个整数 $v_i,w_i,s_i$,用空格隔开,分别表示第 i
种物品的体积、价值和数量。
- $s_i=−1$ 表示第
i
种物品只能用1次; - $s_i=0$ 表示第
i
种物品可以用无限次; - $s_i>0$ 表示第
i
种物品可以使用 $s_i$ 次;
输出格式
输出一个整数,表示最大价值。
数据范围
$0<N,V≤10000<N,V≤1000$
$0<v_i,w_i≤10000<v_i,w_i≤1000$
$−1≤s_i≤1000−1≤s_i≤1000$
输入样例
1 | 4 5 |
输出样例:
1 | 8 |
1 | import java.util.*; |