一些有趣的背包迷题。优化
对于无限背包方案数,至关于单调不降序列方案数。spa
对于\(i\in [a,a+b-1]\)范围内,体积为\(i\)的物品有无限个,求装满\(T\)的方案数。
\(f_{i,j} = f_{i-1,j-a} + f_{i,j-i}\)队列
讨论一下物品个数上界来肯定\(i\)的枚举范围。io
关于多重背包,按照\(\% 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\)class
有\(i\)个物品,第\(i\)个物品有\(i\)个,体积为\(i\),求装满\(T\)的方案数。
分块:block
关于无限背包其实还能够更优秀一些:
\(\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\)便可。math
\(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)\)。枚举