手撕揹包問題,用動態規劃哦

問題描述:

有一個揹包容量爲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]);
}

 

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