多重背包之单调队列优化理论性总结

多重背包之单调队列优化:
若用F[j]表示对容量为j的背包,处理完前i种物品后,背包内物品可达到的最大总价值,并记m = min(n, j / v)。放入背包的第i种物品的数目可以是:0、1、2……,可得:
F[j] = max { F[i - 1] [j – k * v ] + k * w } (0 <= k <= m) ㈠

如何在O(1)时间内求出F[j]呢?
先看一个例子:取m = 2, v = v, w = w, V > 9 * v,
并假设 f(j) = F[i - 1][j],观察公式右边要求最大值的几项:
j = 6v: f(6v)、f(5v)+w、f(4v)+2w 这三个中的最大值
j = 5
v: f(5v)、f(4v)+w、f(3v)+2w 这三个中的最大值
j = 4v: f(4v)、f(3v)+w、f(2v)+2 * w 这三个中的最大值
显然,公式㈠右边求最大值的几项随j值改变而改变,但如果将j = 6 * v时,每项减去6*w,j=5 * v时,每项减去5 * w,j=4 * v时,每项减去4 * w,就得到:
j = 6 * v: f(6 * v)-6 * w、f(5 * v)-5 * w、f(4 * v)-4 * w 这三个中的最大值
j = 5 * v: f(5 * v)-5 * w、f(4 * v)-4 * w、f(3 * v)-3 * w 这三个中的最大值
j = 4 * v: f(4 * v)-4 * w、f(3 * v)-3 * w、f(2 * v)-2 * w 这三个中的最大值
很明显,要求最大值的那些项,有很多重复。

根据这个思路,可以对原来的公式进行如下调整:
假设d = v,a = j / d,b = j % d,即 j = a * d + b,代入公式㈠,并用k替换a - k得:
F[j] = max { F[i - 1] [b + k * d] - k * w } + a * w (a – m <= k <= a) ㈡

对F[i - 1][y] (y= b b+d b+2d b+3d b+4d b+5d b+6d … j)
F[j]就是求j的前面m + 1个数对应的F[i - 1] [b + k * d] - k * w的最大值,加上a * w,如果将F[j]前面所有的F[i - 1][b + k * d] – k * w放入到一个队列,那么,F[j]就是求这个队列最大长度为m + 1时,队列中元素的最大值,加上a * w。因而原问题可以转化为:O(1)时间内求一个队列的最大值。

#如未理解公式推导,可用k的范围代入公式以加深理解。当然刷题是必不可少的的?。

你可能感兴趣的:(ACM)