zoukankan      html  css  js  c++  java
  • 背包整理(1) 01,完全,多重

    背包问题 一   

    01背包:

    1. 一般的题目描述是:有N 件物品和一个容量为V 的背包。放入第i 件物品耗费的费用是Ci,得到的价值是Wi。求解将哪些物品装入背包可使价值总和最大。         

              这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。         

    •  用子问题定义状态:即 dp[i][v] 表示前 i 件物品恰放入一个容量为 v 的背包可以获得的最大价值。
                  //dp[N][V];注意:输入的起始地址为1;初始化dp,都为0;
                  for(i=1 ; i<=N ; i++)
                       for(j= c[i] ; j<=V; j++)//注意是从小到大;
                            dp[i][j]=max(dp[i-1][j],dp[i-1][j-C[i]]+W[i]);
                                 // 则dp[N][V]就是要找的值;
    •  以上方法的时间和空间复杂度均为O(V N),其中时间复杂度应该已经不能再优化了,但空间复杂度却可以优化到O(V)。
                for(i=1 ; i<=N ; i++)
                        for(j= v; j>=c[i]; j--)//注意是从大到小;
                              dp[j]=max(dp[v],dp[v-C[i]]+W[i]);
                                   // 则dp[N][V]就是要找的值;
    •  PS:实际上会有两种情况,一个是恰好装满,dp[0]=0, 其他需要初始化为负无穷;一个只是寻找最优的解决方案,全部初始化为0就行了;

    完全背包:

    1. 这个问题非常类似于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背包来解决为题; 初始化时 dp[V]  都为0; 输入从下标一开始;
             for(int i=1 ; i<=n ;i++)
                 for(int j=c[i]; j<=V; j++)//注意:从小到大;
                    dp[j]=max(dp[j],dp[j-c[i]]+w[i]);
                        //最后的结果就为;dp[V];

     多重背包:

        下面进入关键时刻,完全背包:

          另一种好想好写的基本方法是转化为01背包求解:把第i种物品换成n[i]件01背包中的物品,则得到了物品数为Σn[i]的01背包问题,直接求解,复杂度仍然是O(V*Σn[i])。

          但是我们期望将它转化为01背包问题之后能够像完全背包一样降低复杂度。

          仍然考虑二进制的思想,我们考虑把第i种物品换成若干件物品,使得原问题中第i种物品可取的每种策略——取0..n[i] 件——均能等价于取若干件代换以后的物品。

          另外,取超过n[i]件的策略必不能出现。 

          方法是:将第i种物品分成若干件物品,其中每件物品有一个系数,这件物品的费用和价值均是原来的费用和价值乘以这个系数。使这些系数分别为1,2,4,...,2^(k-1),n[i]-2^k+1,    

          按照总的价值来分,如果那个商品的数量为1,就按01,背包,如果是多个,就按完全背包,来解答;
          看看例题吧:   HDU 2844   HUD 1059

  • 相关阅读:
    mssql 循环的写法,备用
    用了十几年的windows记录下我不知道的几个快捷键
    折腾了下java下webservice,折腾了大半天,居然是eclipse的版本不对
    连接Linux 下mysql 慢的问题,解决之
    解决windows7蓝屏的方法
    MySQL錯誤:Value '00000000' can not be represented as java.sql.Date解決方法[转]
    jdbc连接三种数据库的连接语句写法(备查)
    遇到一个json解析的错误,费了好大的劲,最后发现是少了一个包
    【转】The reference to entity "characterEncoding" must end with the ';' delimiter
    synaptics 插入USB鼠标禁用,网上
  • 原文地址:https://www.cnblogs.com/lovychen/p/3656664.html
Copyright © 2011-2022 走看看