写点东西(关于背包问题)
一些有趣的背包迷题。
Section1
对于无限背包方案数,相当于单调不降序列方案数。
对于\(i\in [a,a+b-1]\)范围内,体积为\(i\)的物品有无限个,求装满\(T\)的方案数。
\(f_{i,j} = f_{i-1,j-a} + f_{i,j-i}\)
讨论一下物品个数上界来确定\(i\)的枚举范围。
Section2
关于多重背包,按照\(\% V\)单调队列优化:
\(f_{i,aV+d} = f_{i,(a-cs)V+d} + cs*W\)
令\(a-cs = k\)有:
\(f_{i,aV+d} - aW = f_{i,kV + d} - csW ; \ \ \ k \geq a - Cnt\)
Section3
有\(i\)个物品,第\(i\)个物品有\(i\)个,体积为\(i\),求装满\(T\)的方案数。
分块:
- 对于体积\(\leq \sqrt{T}\),暴力枚举,使用单调队列。
- 对于体积\(>\sqrt{T}\),用\(Section1\)中的解法解决。
Section4
关于无限背包其实还可以更优秀一些:
\(\prod \frac{1}{1-x^{V_t}} = e^{-\sum_{t} ln(1-x^{V_t})}\)
然后:
\(ln(1-x^{V_t}) = -\int \frac{-V_tx^{V_t-1}}{1-x^V_t} = -\int \sum_{j=0}^{\inf} V_tx^{(j+1)V_t - 1} = -\sum_{j=1}^{\inf} \frac{x^{jV_t}}{j}\)。
调和级数加贡献后多项式\(exp\)即可。
Section4
\(0/1\)背包还可以更加毒瘤一点。
假设每个物品的体积特别小,现在求填满\(T\)的方案数。
按照体积枚举物品,对于同一体积,肯定优先选价值大的,设选\(i\)个的价值为\(W_i\)。
枚举体积\(V\)的剩余类\(d\),有:
\(f_{Vi+d} = f'_{Vj+d} + W_{i-j}\),每次做完一个\(V\)后再\(f_{i} = max(f_{i},f_{i-1})\)。
\(W_{i}\)的斜率递减。
所以对于每一个剩余类,决策单调,用分治解决,复杂度变为\(O(MaxV*TlogT)\)。