美文网首页
01背包空间优化

01背包空间优化

作者: 衣忌破 | 来源:发表于2017-06-23 17:01 被阅读53次

    参考 http://www.2cto.com/kf/201301/184347.html
    条件
    1 每件物品的体积为w1, w2……wn
    2 相对应的价值为 v1, v2.……vn
    3 01背包是在n件物品取出若干件放在空间为total_weight的背包里,使得背包的总体积最大

    01背包没优化的版本

    for (int i = 1; i <= n; i++) {  
      for (int j = 1; j <= total_weight; j++) {  
        if (w[i] > j) {  
          c[i][j] = c[i-1][j];  
        } else {  
            if (c[i-1][j] > v[i]+c[i-1][j-w[i]]) {  
              c[i][j] = c[i-1][j];  
            }  
            else {  
              c[i][j] =  v[i] + c[i-1][j-w[i]];  
            }  
        }  
      }  
    }
    

    注意到状态转移方程

     c[i][j] = max{c[i-1][j], c[i-1][j-w[i]]+v[i]} 
    

    每一次c[i][j]改变的值只与c[i-1][x] {x:1...j}有关c[i-1][x]是前一次i循环保
    存下来的值,因此,可以将c缩减成一维数组状态转移方程转换为

    c[j] = max(c[j], c[j-w[i]]+v[i]);
    

    并且,我们注意到状态转移方程,每一次推导c[i][j]是通过c[i-1][j-w[i]]来推导的,而不是通过c[i][j-w[i]]。因此,j的扫描顺序应该改成从大到小。否则,第i次求c数组,必然先求的c[j-w[i]]的值(即c[i][j-w[i]]),再求c[j] (即c[i][j])的值,由于j递增,那么状态方程就成为下面这个样子了

    c[i][j] = max(c[i-1][j], c[i][j-w[i]]+v[i])
    

    显然不符合题意所以,上面的代码变为

    for (int i = 1; i <= n; i++) {  
       for (int j = total_weight; j >= 1; j--) {  
         if (w[i] > j) {  
           c[j] = c[j]; //表示第i次与第i-1次相等,这里因为c[j]本来就保存这上一次的值,所以这里不需变化  
         } else {  
           //说明第i件物品的重量小于背包的重量,所以可以选择第i件物品放还是不放  
             if (c[j] > v[i]+c[j-w[i]]) {  
               c[j] = c[j];  
             }  
             else {  
               c[j] =  v[i] + c[j-w[i]];  
             }  
         }  
       }  
     }  
    

    把不必要的语句去掉即可完成优化

    for (int i = 1; i <= n; i++) {  
      for (int j = total_weight; j >= w[i]; j--) {  
        if (c[j] <= v[i] + c[j-w[i]])  
          c[j] = v[i] + c[j-w[i]];  
      }  
    }  
    

    最后关于j的扫描顺序改为从大到小的图解。

    动态规划.png

    假设现在需要求i件物品时c[10] (即j=10)的值显然它是需要i-1时的c[10]和c[9]去推导出并将求得的值赋值给c[10],从图中不难看出当j的有小到大顺序时是有问题的。因为推导c[10]所需的c[9]因为第i-1件物品下的c[9],显然这种情况下的c[9]并不是第i-1件物品时所对应的c[9]的值与转移方程矛盾。

    相关文章

      网友评论

          本文标题:01背包空间优化

          本文链接:https://www.haomeiwen.com/subject/ccvccxtx.html