zoukankan      html  css  js  c++  java
  • 多重背包之单调队列优化理论性总结

    多重背包之单调队列优化:
    若用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的范围代入公式以加深理解。当然刷题是必不可少的的?。

  • 相关阅读:
    django restful framework 有哪些功能(10条)
    Restful 规范
    eclipse编辑环境下导入springmvc的源码
    java.lang.NoSuchMethodException: .<init>()
    spring项目出现无法加载主类
    元素 "context:component-scan" 的前缀 "context" 未绑定。
    BeanPostProcessor出现init方法无法被调用Invocation of init method failed
    spring学习笔记
    springmvc学习笔记
    打印圈1圈2
  • 原文地址:https://www.cnblogs.com/DeepJay/p/12025225.html
Copyright © 2011-2022 走看看