Note 01 背包基础
问题模型:对于 \(n\) 个物品 \((w,v)\),取其中一部分,使得 \(\sum w<V\) 的情况下求 \((\sum v)_{\max}\)。
这个问题无论采用什么算法解决,第一步都是指定一个顺序,一个一个物品去考虑。
在这一步,我们发现,各个物品间是独立的(后面也有例外,再说),我们把他们划分成相对独立的阶段处理。
动态规划的思想通过记录每一个阶段不同状态的最优决策除去阶段中冗余状态,加速计算。
01 背包
每种物品只有一个。
设计 \(f(i,j)\) 表示考虑到第 \(i\) 个物品,容量为 \(j\) 的最优决策。
有 \(f(i,j)=\max\set{f(i-1,j),f(i-1,j-w_i)+c_i}\)。
可以实现空间复杂度 \(O(V)\),时间复杂度 \(O(nV)\)。
完全背包
每种物品有无限个。
状态设计同上。
实际上是想让“一次转移”变成“多次转移”,在压缩的时候换一下转移顺序即可实现。
空间复杂度 \(O(V)\),时间复杂度 \(O(nV)\)。
多重背包
每种物品个数为 \(k_i\) 个。
-
二进制拆分思路
转化为 01 背包问题,利用二进制拆分把他等价拆分成 \(\log\) 个物品,可以实现 \(O(V\sum_{i=1}^n \log k_i)\)。 -
单调队列优化思路
对于一个物品 \((w,v,k)\) 来说,同余于 \(w\) 的各个位置转移起来是相对独立的,可以分开考虑。
发现 \(f(i,j)=\max\set{f(i-1,j-kw_i)+kv_i}\),运用单调队列和前面 PST 的思想,一边转移一边往单调队列里面插入一个数即可。
核心问题:比较键值是什么?
发现往后一个 \(w_i\),就少一个 \(v_i\),相对关系可以使用 \(f(i-1,aw_i+b)-av_i\) 这个键值刻画。
代码实现详见 P1776。
分组背包
对于 01 背包问题,将物品分为 \(k\) 组,每组中最多只能选取一个物品。
仍然考虑设 \(f(i)\) 表示用 \(i\) 的空间可以获得最大收益。
同组强制用上一层转移,可以实现时间复杂度 \(O(nV)\),空间复杂度 \(O(V)\),
代码详见 P1757。

浙公网安备 33010602011771号