手撕揹包问题,用动态规划哦

问题描述:

有一个揹包容量为10 ,现在4件物品,物品的重量和价值如下,请问揹包装最大的价值是多少?

1.首先解答这种问题,用动态规划的话,首先还是老套路,四部曲(不明白的,可以看我往期动态规划的博客)

1.确定状态(两个核心:1最后一步 2化成子问题)

2转移方程

3开始和边界条件

4计算顺序

 

 (1)首先第一个,确定状态

   w:表示揹包容量

  W[2,3,4,5] :表示每件物品的重量

  v[3,4,5,8]:表示每件物品的价值

  分析“最后一步”是: 现在有k(这里是4)件物品可以选,揹包能装最大的价值。f(k,w) 表示当揹包容量为w,有k件物品可以选,揹包能装最大的价值

  化成子问题 : 假如先看最后编号为k(这里是4)的物品, 这个时候有两种情况

                      放不下: f(k,w) = f(k - 1 , w)

                      放得下 :又分两种情况:

                                     拿到包里:f(k,w) = f(k - 1 , w-Wk) +v[k]

                                      不拿:      f(k,w) = f(k - 1 , w)

(2)转移方程

     

(3)开始和边界条件

用一个表格来分析,首先f(0,0),f(0,1)....f(0,8)自然是0,因为编号为0的物体不存在,所以为0。

接着f(0,0),f(1,0)....f(8,0)自然是0,因为揹包容量为0,所有物品放不进去,所以为0

                

(4)计算顺序

   其实就是从f[0]开始计算而已,并把他们都记录下来

 //揹包问题
backpack() {
      var n = 10; //揹包容量
      var w = [0, 2, 3, 4, 5]; //重量
      var v = [0, 3, 4, 5, 8]; //价值
      var f = []; //下面构建二维数组的,f[k][w]代表前k件物品所能接受的最大值
      //初始化二维数组
      for (var i = 0; i < 5; i++) {
        f[i] = [];
        for (var j = 0; j < n + 1; j++) {
          f[i][j] = 0;
        }
      }

      for (var i = 1; i < 5; i++) {
        for (var j = 1; j < n + 1; j++) {
          if (w[i] > j) {
            f[i][j] = f[i - 1][j];
          } else {
            f[i][j] = Math.max(f[i - 1][j], f[i - 1][j - w[i]] + v[i]);
          }
        }
      }
     
     console.log("揹包问题结果", f[4][8]);
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章