zoukankan      html  css  js  c++  java
  • 完全背包

    完全背包问题
    与01背包的区别
    01背包:每种物品只能取一件
    完全背包:每种物品能取无限件

    按照01背包思路的状态转移方程
    f[i][v] = max{f[i-1][v-k*c[i]] + k*w[i] | 0 <= k*c[i] <= v};

    完全背包转化为01背包的思路
    将一种物品拆成多件物品

    二进制思想
    第i种物品拆成费用为 c[i]*2^k, 价值为 w[i]*2^k 的若干件物品, c[i]*2^k <= V

    c[i] * n = V
    n = V/c[i]
    n = 2^k
    2^k = V/c[i]
    k = log(V/c[i])

    选n件第i种物品,可以表示为 选2^k件第i种物品
    最优策略为若干个2^k件物品的和 若干个--若干种物品 每种物品2^k个

    复杂度:O(log V/c[i])

    O(VN)的算法

    //O(VN)算法的伪代码
    for i = 1..N
    for v = 0..V
    f[v] = max{f[v],f[v-cost]+weight}
    //对比01背包的伪代码
    for i = 1..N
    for v = V..0
    f[v] = max{f[v],f[v-cost]+weight}

    * 回顾01背包的思路
    在要装入的物品顺序一定时,背包某一时刻的体积是固定的,可以直接对应背包中装入的物品,确保判断第i种物品是否装入时,已经对第i-1种物品判断过了,每种物品只执行一次。f[i-1][v-c[i]]已经确定第i种物品只能装入的体积为c[i]。

    * O(VN)的思路
    加选第i种物品,需要一个可能已选入第i种物品的子结果f[i][v-c[i]],没有限定第i种物品的加入的体积大小

    ## O(VN)的状态转移方程
    _f[i][v] = max{f[i-1][v],f[i][v-c[i]]+w[i]}_

    //与当前的背包的最大价值相比较,如果再加入一件该物品后背包的最大价值 f[v-c[i]]+w[i] 变得更大,就加入,
    procedure CompletePack(cost,weight)
    for v = cost..V
    f[v] = max{f[v],f[v-c[i]]+w[i]}


    拆分成的子问题是:在背包的容量为任意值时,是否要加入当前的这个物品

  • 相关阅读:
    linux学习之uniq
    hive学习05 参数设置
    【python】调用sm.ms图床api接口,实现上传图片并返回url
    【python】列表与数组之间的相互转换
    更新yum源
    要把RAID5创建卷组
    named-checkconf -z /etc/named.conf
    function_exists
    trigger_error
    命名空间
  • 原文地址:https://www.cnblogs.com/HackHer/p/6171806.html
Copyright © 2011-2022 走看看