母题1:01背包
考虑 \(f[i,j]\) 表示前 \(i\) 个物品体积为 \(j\) 的答案,答案可以从前 \(i-1\) 个物品继承或选取当前物品,\(f[i,j]=\max(f[i-1][j],f[i-1][j-v]+w)\)。
母题2:完全背包(from 1)
状态同上,转移本来应该为 \(f[i,j]=\max(f[i-1][j-v]+w,f[i-1][j-2v]+2w,\dots,f[i-1][j-kv]+kw)\)(设 \(j-kv\ge 0,j-(k+1)v<0\))。发现 \(f[i,j-v]=\max(f[i-1][j-2v]+w,f[i-1][j-3v]+2w,\dots,f[i-1][j-kv]+(k-1)w)\),恰好是少了一个 \(w\),于是我们可以用 \(f[i,j]=\max(f[i][j-v]+w)\)。
母题3:多重背包(from 1)
转移应该为 \(f[i,j]=\max(f[i-1,j-v]+w,f[i-1,j-2v]+2w,\dots,f[i-1,j-sv]+sw)\)(这里不管超出的情况)。
可以直接暴力,也有两种优化:
- 二进制优化,很好理解,对于一个物品若可选 \(5\) 个,可以拆成两个物品 \(1\) 倍和 \(4\) 倍,然后做
01背包,带一只 \(\log\)。 - 单调队列优化,不好理解,就是对于 \(j\bmod v\) 同一个余数的情况一起处理,发现对于每种物品就是长度为 \(s\) 的定长滑动窗口求最值模型。
母题4:分组背包(from 1)
就是某些物品在一个组内,组内只能选其一。
转移可以用 \(f[i,j]=f[i-1,j-v_k]+w_k\)(注意,同一组的物品对应一个 \(i\),这样从上一层转移可以保证不会出现一组内的物品选多个)。
母题5:有依赖的背包问题(from 4)
考虑树形 DP。
处理出子树内的答案,然后根节点必选,子树内就是分组背包,有体积那么大的个数在一组内。
以上就是5个模型
变式1
类背包,表示状态类似于,体积变为余数,考虑 \(+,\times\)。01背包模型
2
用小的组合出大的,就是给定一些物品,问凑出的个数,考虑完全背包(母题2),改变一下属性为 bool。
3
本质还是背包,分类讨论,状态是由差值表示。01背包模型
4
利用背包求解博弈论,需要知道基本的必胜态、必败态。
然后考虑余数。01背包模型
5
01背包套矩阵快速幂。
总结
背包问题一般比较难的都是01背包(变式2很明显是完全背包,而且转移就是基本的转移,比母题还简单)。
题目中出现的数值可以成为“体积”。
转移有时需要分类讨论。