• 01背包、完全背包


    有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,
    且价值总和最大。

    基本思路
    每种物品仅有一件,可以选择放或不放。

    用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。
    则其状态转移方程便是:f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}。

    注意f[i][v]有意义当且仅当存在一个前i件物品的子集,其费用总和为v。所以按照这个方程递推完毕后,
    最终的答案并不一定是f[N] [V],而是f[N][0..V]的最大值。如果将状态的定义中的“恰”字去掉,
    在转移方程中就要再加入一项f[i][v-1],这样就可以保证f[N] [V]就是最后的答案。

    让v递减是为了保证第i次循环中的状态F[i; v]是由状态F[i -1; v - Ci]递
    推而来,否则顺着来的话F[i;v]是有本次循环得到的f[i-1,v-ci]来递推的

    换句话说,这正是为了保证每件物品只选一次,保证在考虑“选入
    第i件物品”这件策略时,依据的是一个绝无已经选入第i件物品的子结果 F[i -1; v -Ci]

    所以   01背包为

    for i=1..N
    for v=V..0
    f[v]=max{f[v],f[v-c[i]]+w[i]};

    完全背包

    F[i; v] = max(F[i-1; v]; F[i; v- Ci] +Wi)

    有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。

    这个问题非常类似于01背包问题,所不同的是每种物品有无限件。也就是从每种物品的角度考虑,与它相关的策略已并非取或不取两种,而是有取0件、取1件、取2件……等很多种。如果仍然按照解01背包时的思路,令f[i][v]表示前i种物品恰放入一个容量为v的背包的最大权值。仍然可以按照每种物品不同的策略写出状态转移方程,像这样:f[i][v]=max{f[i-1][v-k*c[i]]+k*w[i]|0<=k*c[i]<= v}。

    转化为01背包问题求解
    既然01背包问题是最基本的背包问题,那么我们可以考虑把完全背包问题转化为01背包问题来解。最简单的想法是,考虑到第i种物品最多选V/c [i]件,于是可以把第i种物品转化为V/c[i]件费用及价值均不变的物品,然后求解这个01背包问题。这样完全没有改进基本思路的时间复杂度,但这毕竟给了我们将完全背包问题转化为01背包问题的思路:将一种物品拆成多件物品。

    更高效的转化方法是:把第i种物品拆成费用为c[i]*2^k、价值为w[i]*2^k的若干件物品,其中k满足c[i]*2^k<V。这是二进制的思想,因为不管最优策略选几件第i种物品,总可以表示成若干个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-c[i]]+w[i]};

    keep moving...
  • 相关阅读:
    Samba网络配置
    嵌入式汇编程序
    GDB常用命令
    Everything搜索结果显示0 Object
    关于值类型和引用类型
    Main()

    利用python脚本自动下载ICML会议接受的文章
    如何从mac下的photos导出照片
    Erlang语言研究综述
  • 原文地址:https://www.cnblogs.com/xxx0624/p/2598127.html
Copyright © 2020-2023  润新知