背包问题总结

背包问题是一大类问题。
我们不妨设有\(n\)个物品,背包容量为\(m\),每个物品大小为\(c\),个数为\(d\),价值为\(w\)。
大写字母表示求和。
01背包,完全背包,分组背包:直接dp即可。时间复杂度\(O(nm)\)。
多重背包:单调队列优化或二进制拆分。\(O(nm)\)或\(O(nmlogd)\)。枚举余数进行单调队列。
树形背包:选择父亲才能选择儿子。
树形dp或者dfs序列上dp。建议后者。\(O(nm)\)。
超大背包:体积很大,价值很小。
按照价值DP即可。dp(i,j)表示考虑到i,价值为j,最小体积。\(O(n^2w)\),即\(O(nW)\)。
价值体积都很大的背包:中途相遇法。\(O(2^{\frac{n}{2}})\)。
01背包,\(n,m\)都比较大,但\(c\)很小:
把物品按照\(c\)整理。
按照c去依次计算,设\(f(x,i)\)表示考虑到体积为\(x\)的物品,容量为\(i\)。
对于模\(x\)意义下相等的数,从小到大满足决策单调性,使用分治,可以把复杂度降低至\(O(nlogn+mclogm)\)。
分数背包:直接按照\(\frac{w}{c}\)排序,贪心选择。\(O(nlogn)\)。‘
超多背包:\(m,d\)都很大。只有\(w\)比较小。
考虑分数背包的贪心做法,但这个显然是错误的。
不过可以发现,只有对于每个物品的零散部分才可能出错。
把每个物品拆分为两个部分:小于等于\(w\)的部分。大于\(w\)的部分。
后者直接贪心即可。前者使用”超大背包“和单调队列优化即可。\(O(n^2w^2)\)。

没了。

希望自己情感事业一帆风顺。

上一篇:WC2021 游记


下一篇:【c++基础】linux系统代码调试