• 背包九讲-01背包


    tianyi cui 的背包九讲老版本:http://love-oriented.com/pack/

    更新后的版本PDF下载:http://cuitianyi.com/blog/%E3%80%8A%E8%83%8C%E5%8C%85%E9%97%AE%E9%A2%98%E4%B9%9D%E8%AE%B2%E3%80%8B2-0-alpha1/

    新版pdf下载地址2:http://download.csdn.net/detail/tangzhangpeng/5591321

    本文实现了新版本第一章 “01背包问题”,代码中的注释也是针对新版本。

    pdf 1.5 小节中的小错误,常数优化应该是

    ,对Ci求和而不是对Wi求和

    对1.5常数优化的解释:前 i  个物品获得的空间最小值是:,即后面i~N个物品装满后剩余的空间,若剩余空间小于Ci,则为Ci

    算法测试数据来自:http://www.cnblogs.com/jisi5789/archive/2013/04/11/3015745.html

    相关代码如下:

      1 #include<iostream>
      2 #include<string>
      3 #include<vector>
      4 using namespace std;
      5 
      6 inline int max(int a, int b)
      7 {
      8     return a>b?a:b;
      9 }
     10 
     11 int ZeroOnePack1(int n, int v, int c[], int w[], bool needFull)
     12 {
     13     //根据tianyi cui背包九讲1.2的最原始的解法
     14     //时间空间复杂度均为O(nv)
     15     // n 物品数量
     16     // v 背包容量
     17     // c[] 物品耗费的空间,从c[1]开始
     18     // w[] 物品的价值,从w[1]开始
     19     // needFull 背包是否需要完全装满
     20     const int MIN = numeric_limits<int>::min(); //表示负无穷
     21     int **f = new int*[n+1];
     22     for(int i = 0; i < n+1; i++)
     23         f[i] = new int[v+1];
     24     if(needFull)  //初始化细节详见 背包九讲1.4
     25     {
     26         for(int i = 0; i <= n; i++)
     27             for(int j = 0; j <= v; j++)
     28                 f[i][j] = MIN;
     29         f[0][0] = 0;
     30     }
     31     else 
     32     {
     33         for(int i = 0; i <= n; i++)
     34             for(int j = 0; j <= v; j++)
     35                 f[i][j] = 0;
     36     }
     37     
     38     for(int i = 1; i <= n; i++)
     39         for(int j = c[i]; j <= v; j++)
     40         { 
     41             f[i][j] = max(f[i - 1][j], f[i - 1][j - c[i]] + w[i]);
     42         }
     43     if(f[n][v] < 0)return -1;  //针对背包装满的情况,没有满足的答案
     44     return f[n][v];
     45 }
     46 
     47 int ZeroOnePack2(int n, int v, int c[], int w[], bool needFull)
     48 {
     49     //根据tianyi cui背包九讲1.3在1.2的基础上优化空间复杂度后的解法
     50     //时间复杂度均为O(nv),空间复杂度为O(v)
     51     // n 物品数量
     52     // v 背包容量
     53     // c[] 物品耗费的空间,从c[1]开始
     54     // w[] 物品的价值,从w[1]开始
     55     // needFull 背包是否需要完全装满
     56     const int MIN = numeric_limits<int>::min(); //表示负无穷
     57     int *f = new int[v+1];
     58     if(needFull)  //初始化细节详见 背包九讲1.4
     59     {
     60         for(int i = 0; i <= v; i++)
     61             f[i] = MIN;
     62         f[0] = 0;
     63     }
     64     else 
     65     {
     66         for(int i = 0; i <= v; i++)
     67             f[i] = 0;
     68     }
     69     
     70     for(int i = 1; i <= n; i++)
     71         for(int j = v; j >= c[i]; j--)
     72         { 
     73             f[j] = max(f[j], f[j - c[i]] + w[i]);
     74         }
     75     if(f[v] < 0)return -1;  //针对背包装满的情况,没有满足的答案
     76     return f[v];
     77 }
     78 
     79 int ZeroOnePack3(int n, int v, int c[], int w[], bool needFull)
     80 {
     81     //根据tianyi cui背包九讲1.5,在1.3的基础上有个常数的优化,在v较大时,有明显优势
     82     //时间复杂度均为O(nv),空间复杂度为O(v)
     83     // n 物品数量
     84     // v 背包容量
     85     // c[] 物品耗费的空间,从c[1]开始
     86     // w[] 物品的价值,从w[1]开始
     87     // needFull 背包是否需要完全装满
     88     const int MIN = numeric_limits<int>::min(); //表示负无穷
     89     int *f = new int[v+1];
     90     if(needFull)  //初始化细节详见 背包九讲1.4
     91     {
     92         for(int i = 0; i <= v; i++)
     93             f[i] = MIN;
     94         f[0] = 0;
     95     }
     96     else 
     97     {
     98         for(int i = 0; i <= v; i++)
     99             f[i] = 0;
    100     }
    101     
    102     int csum = 0;
    103     c[0] = 0;
    104     for(int i = 1; i <= n; i++)csum += c[i];
    105     for(int i = 1; i <= n; i++)
    106     {
    107         csum -= c[i-1];
    108         for(int j = v; j >= max(c[i], v - csum); j--)
    109         { 
    110             f[j] = max(f[j], f[j - c[i]] + w[i]);
    111         }
    112     }
    113     if(f[v] < 0)return -1;  //针对背包装满的情况,没有满足的答案
    114     return f[v];
    115 }
    116 
    117 int main()
    118 {
    119     //87
    120     int c[] = {0,2,7,3,4,8,5,8,6,4,16};
    121     int w[] = {0,15,25,8,9,15,9,13,9,6,14};
    122     int result = ZeroOnePack3(10, 34, c, w, true);
    123     cout<< result <<endl;
    124     
    125     //82
    126     int c1[] = {0,4,5,7,2,8,3,6,1,10,9};
    127     int w1[] = {0,25,14,15,4,14,5,8,1,10,2};
    128     int result1 = ZeroOnePack3(10, 34, c1, w1, true);
    129     cout<< result1 <<endl;
    130     
    131     //-1
    132     int c2[] = {0,2,3,6};
    133     int w2[] = {0,15,10,16};
    134     int result2 = ZeroOnePack3(3, 10, c2, w2, true);
    135     cout<< result2 <<endl;
    136     
    137     //85
    138     int c3[] = {0,2,8,4,4,8,7,8,5,16,16};
    139     int w3[] = {0,15,25,9,9,15,12,12,6,14,9};
    140     int result3 = ZeroOnePack3(10, 34, c3, w3, true);
    141     cout<< result3 <<endl;
    142     
    143     //83
    144     int c4[] = {0,4,5,7,2,8,3,9,6,1,10};
    145     int w4[] = {0,25,14,15,4,14,5,14,8,1,10};
    146     int result4 = ZeroOnePack3(10, 34, c4, w4, true);
    147     cout<< result4 <<endl;
    148 }
    View Code

     【版权声明】转载请注明出处 http://www.cnblogs.com/TenosDoIt/p/3139092.html

  • 相关阅读:
    查询session内容
    7个月工作总结
    clob字段的值插入和查询N种方法【包括java调用存储过程传入clob参数】
    javascript实现jsp页面的打印预览
    Ext:添加进度条
    js实现非模态窗口增加数据后刷新父窗口数据
    websphere:rs.getDate()无法使用的解决方法
    POI实现excel各种验证和导入的思路总结
    Tomcat迁移到WebsphereURL获取中文参数乱码问题
    JS函数参数
  • 原文地址:https://www.cnblogs.com/TenosDoIt/p/3139092.html
Copyright © 2020-2023  润新知