国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

經典動態規劃:0-1 背包問題

開發 前端
月黑風高的夜晚,張三開啟了法外狂徒模式:他背著一個可裝載重量為 W 的背包去地主家偷東西。

[[392731]]

問題背景

月黑風高的夜晚,張三開啟了法外狂徒模式:他背著一個可裝載重量為 W 的背包去地主家偷東西。

地主家有 N 個物品,每個物品有重量和價值兩個屬性,其中第 i 個物品的重量為 wt[i],價值為 val[i]。

問張三現在用這個背包裝物品,最多能裝的價值是多少?

舉例:

  • N = 3 //地主家有三樣東西
  • wt = [2,1,3] //每樣東西的重量
  • val = [4,2,3] //每樣東西的價值
  • W = 4 //背包可裝載重量

算法應該返回 6.

因為選擇第一件物品和第二件物品,在重量沒有超出背包容量下,所選價值最大。

如果每種物品只能選 0 個或 1 個(即要么將此物品裝進包里要么不裝),則此問題稱為 0-1 背包問題;如果不限每種物品的數量,則稱為無界(或完全)背包問題。

今天這篇文章我們只關注 0-1 背包問題,下一篇文章再聊完全背包問題。

那我們是如何選擇要裝入的物品的?

思路初探

首先,質量很大價值很小的物品我們先不考慮(放著地主家金銀財寶珍珠首飾不偷,背出來一包煤...,那也就基本告別盜竊行業了...)

然后呢?再考慮質量大價值也大的?還是質量較小價值也稍小的?

我們自然而然想到:裝價值/質量 比值最大的,因為這至少能說明,此物品的“價質比”最大(也即貪心算法,每次選擇當前最優)

那么這樣裝能保證最后裝入背包里的價值最優嗎?

我們先來看一個例子:

假設有 5 個物品,N = 5,每種物品的質量與價值如下:

  • W : 20, 30, 40, 50, 60
  • V : 20, 30, 44, 55, 60
  • V/W: 1, 1, 1.1, 1.1, 1

背包容量為 100

如果按上述策略:優先選“價質比”最大的:即第三個和第四個物品

  • 此時質量:40+50=90
  • 價值:44+55 =99

但我們知道,此題更優的選擇策略是:選第一個,第二個和第四個

  • 此時質量:20+30+50=100
  • 價值:20+30+55=105

所以,我們的“價質比”這種貪心策略顯然不是最優策略。

讀過一文學懂動態規劃這篇文章的讀者會發現,之前文章中兌換零錢例子我們最開始也是采取貪心策略,但最后發現貪心不是最優解,由此我們引出了動態規劃。

沒錯,今天這題也正是動態規劃又一經典的應用。

解題思路

根據動之前的文章我們知道,動態規劃的核心即:狀態與狀態轉移方程。

那么此題的狀態是什么呢?

狀態

何為狀態?

說白了,狀態就是已知條件。

重讀題意我們發現:此題的已知條件只有兩個:

  • 背包容量
  • 可選的物品

題目要求的是在滿足背包容量前提下,可裝入的最大價值。

那么我們可以根據上述狀態定義出 dp 數組,即:

dp[i][w] 表示:對于前i個物品,當前背包的容量為w,這種情況下可以裝的最大價值是dp[i][w]

我們自然而然的考慮到如下特殊情況:

當 i = 0 或 w = 0,那么:

dp[0][...] = dp[...][0] = 0

解釋:

對前 0 個物品而言,無論背包容量等于多少,裝入的價值為 0;

當背包容量為 0 時,無論裝入前多少個物品(因為一個都裝不進去),背包里的價值依舊為 0。

根據這個定義,我們求的最終答案就是dp[N][W]

我們現在找出了狀態,并找到了 base case,那么狀態之間該如何轉移呢(狀態轉移方程)?

狀態轉移方程

dp[i][w] 表示:對于前i個物品,當前背包的容量為w,這種情況下可以裝的最大價值是dp[i][w]。

思考:對于當前第 i 個物品:

  • 如果沒有把第 i 個物品裝入包里(第 i 個物品質量大于當前背包容量):那么很顯然,最大價值dp[i][w]應該等于dp[i - 1][w],沒有裝進去嘛,故當前背包總價值就等于之前的結果,即第i - 1 個物品之前的總價值 。
  • 如果把第 i 個物品裝入了包里,那么 dp[i][w]應該等于什么呢?

它應該等于下面兩者里的較大值:

  1. dp[i - 1][w] //前i - 1個物品,背包所裝的最大價值
  2. dp[i - 1]w - wt[i]] + val [i] //當前第 i 個物品我裝里邊了,那么此時背包裝入的總價值即為:當前第 i 個物品的價值 val [i] + 第 i 個物品之前,背包容量為w - wt[i](w 減去當前第 i 個物品的質量)dp[i - 1]w - wt[i]] 時的價值

上述兩個如果可以寫成以下代碼:

  1. //如果第i個物品質量大于當前背包容量 
  2. if (wt[i] > W) { 
  3.  dp[i][W] = dp[i-1][W];  //繼承上一個結果 
  4. else { 
  5. //在“上一個結果價值”和“把當前第i個物品裝入背包里所得到價值”二者里選價值較大的 
  6.  dp[i][W] = Math.max(dp[i-1][W],dp[i-1][W-wt[i]] + val[i]) 

例子

我們接來下再用一個具體的例子,來理解狀態和狀態轉移方程。

現在我們有 4 個物品,物品對應的價值與質量分別如上圖左側所示:

  • 6, 4
  • 2,5
  • 1, 4
  • 8, 1

Step 1

我們首先初始化一行和一列 0,分別對應dp[0][w] 和 dp[i][0]。

那么第一個問號處應該填什么呢?

我們根據上述表述的狀態轉移關系來判斷:

當前第一個物品的重量 4 > 背包容量,故裝不進去,所以繼承上一個結果。

上一個結果是什么呢?

就是第 i - 1個物品,也就是第 0 個,和W = 1時的價值:

  1. if (wt[i] > W) { 
  2.  dp[i][W] = dp[i-1][W];  //繼承上一個結果 

此時方框里的值為 0,故第一個問號這里應該填 0

Step 2

現在我們走到了當背包容量 W = 2 的時候,此時當前 i (依舊第一個物品)能否裝進背包里呢?

我們發現 4 > 2,此時還是裝不進去,那么同樣繼承上一個結果。

上一個結果是 i 不變(依舊是第 **0 **個物品),W = 2,所以結果依舊為 0。

Step 3

現在來到 W = 3,發現依舊裝不進去,所以填 0。

Step 4

下一步到 W = 4 這里了,

此時物品重量 4 = 4(背包容量),可以裝里,那么按照之前狀態轉移關系應該是:

  1. else { 
  2. //在“上一個結果價值”和“把當前第i個物品裝入背包里所得到價值”二者里選價值較大的 
  3.  dp[i][W] = Math.max(dp[i-1][W],dp[i-1][W-wt[i]] + val[i]) 

Option A:

  • 上一個結果 : dp[i - 1][w],即dp[0][4] = 0

Option B:

  • 把當前第 i 個物品裝入背包里所得到價值:dp[i - 1]W - wt[i]] + val [i]

此時第一個物品的重量為 4,背包容量為 4,

故要想裝入重量為 4 的此物品,那么背包先前的容量必須為當前背包容量 - 當前物品容量:4 - 4 = 0。

我們隨即找到在沒裝入此物品(重量為 4,價值為 6)之前的dp[i -1]W - wt[i]] = dp[0][0] = 0

那么dp[i -1]W - wt[i]] + val [i] = 0 + 6 = 6

6 和 0 選擇一個最大值,所以這里問號處應填入6

Step 5

下一步我們來到 W = 5 這里,此時依舊是第一個物品,質量 4 < 5(背包容量),我們可以裝里邊。

然后我們在

Option A:

  • 上一個結果 :dp[0][5] = 0

Option B:

  • 把當前第 i 個物品裝入背包里所得到價值:dp[i -1]W - wt[i]] + val [i]

此時第一個物品的重量為 4,背包容量為 5

故要想裝入重量為 4 的此物品,那么背包先前的容量必須為:當前背包容量 - 當前物品容量:5 - 4 = 1 ,

我們隨即找到在沒裝入此物品(重量為 4,價值為 6)之前的dp[i - 1]W - wt[i]] = dp[0][1] = 0

那么dp[i -1]W - wt[i]] + val [i] = 0 + 6 = 6

選擇一個最大值,即 6,所以此處應該填入 6

我們根據以上狀態轉系關系,依次可以填出空格其它值,最后我們得到整個 dp 數組:

V W 0 1 2 3 4 5 6
0 0 0 0 0 0 0 0 0
6 4 0 0 0 0 6 6 6
2 5 0 0 0 0 6 6 6
1 4 0 0 0 0 6 6 6
8 1 0 8 8 8 8 14 14

最后的 dp[4][6]:考慮前四個物品,背包容量為 6 的情況下,可裝入的最大價值,即為所求。

(注意:我們在這里求的是 0-1 背包問題,即某一個物品只能選擇 0 個或 1 個,不能多選!)

代碼

根據以上思路,我們很容易寫出代碼:

兩層 for 循環

外層循環 i 遍歷物品(即前幾個物品):

  1. for(int i = 1;i <=N;i++){ 
  2.   ... 

內層循環 j 遍歷 1~W(背包容量)之間的整數值:

然后寫入狀態轉移方程

  1. for(int j = 0;j <= W;j++){ 
  2.   //外層循環i,如果第i個物品質量大于當前背包容量 
  3.     if (wt[i] > W) { 
  4.         dp[i][W] = dp[i-1][W];  //繼承上一個結果 
  5.     } else { 
  6.         //在“上一個結果價值”和“把當前第i個物品裝入背包里所得到價值”二者里選價值較大的 
  7.         dp[i][W] = Math.max(dp[i-1][W],dp[i-1][W-wt[i]] + val[i]) 
  8.     } 

由此我們給出完整代碼:

  1. class solution{ 
  2.   public int knapsackProblem(int[] wt,int[] val,int size){ 
  3.     //定義dp數組 
  4.     int[][] dp = new int[wt.length][size]; 
  5.     //對于裝入前0個物品而言,dp數組儲存的總價值初始化為0 
  6.     for(int i = 0;i < size;i++){ 
  7.      int[0][i] = 0; 
  8.     } 
  9.     //對于背包容量W=0時,裝入背包的總價值初始化為0 
  10.     for(int j = 0;j < size;j++){ 
  11.      int[j][0] = 0; 
  12.     } 
  13.     //外層循環遍歷物品 
  14.     for(int i = 1;i <= N;i++){ 
  15.      //內層循環遍歷1~W(背包容量) 
  16.      for(int j = 0;j <= W;j++){ 
  17.       //外層循環i,如果第i個物品質量大于當前背包容量 
  18.          if (wt[i] > W) { 
  19.              dp[i][W] = dp[i-1][W];  //繼承上一個結果 
  20.          } else { 
  21.              //在“上一個結果價值”和“把當前第i個物品裝入背包里所得到價值”二者里選價值較大的 
  22.              dp[i][W] = Math.max(dp[i-1][W],dp[i-1][W-wt[i]] + val[i]) 
  23.          } 
  24.      } 
  25.     } 
  26.   } 

只要我們定義好了狀態(dp 數組的定義),理清了狀態之間是如何轉移的,最后的代碼水到渠成。

本文所說的這個 0-1 背包問題,Leetcode 上并沒有這個原題,所以對于背包問題,最重要的是它的變種。

背包問題是一大類問題的統稱,很大一部分動態規劃的題深層剖析都可以轉換為背包問題。

所以還需要理解體會背包問題的核心思想,再將此種思想運用到其它一類背包問題的問題上。

 

那么背包問題還有哪些變化呢?我們下期見~

 

責任編輯:武曉燕 來源: 碼農田小齊
相關推薦

2022-01-17 13:31:53

value背包解法

2021-01-19 05:46:45

背包數組容量

2023-06-26 19:25:18

效率消息中心業務線

2021-03-15 06:04:47

斐波那契數列背包問題算法

2022-12-23 08:03:45

西瓜業務SEO前端

2021-02-09 09:55:24

動態規劃

2017-10-23 12:55:46

項目設計師流程

2023-10-30 07:30:08

VeCDP火山引擎

2024-02-29 07:42:00

數據系統數據庫數據處理

2024-05-15 07:26:50

RedisBigKey優化

2021-02-05 07:16:13

C語言負數的存儲

2022-07-13 11:17:00

大數據規劃

2025-06-19 08:00:00

Python算法背包問題

2023-01-06 08:42:41

動態規劃字符

2023-06-26 07:31:44

屬性物品背包

2011-03-10 13:18:54

SQLwhere

2021-10-28 18:58:57

動態規劃數據結構算法

2022-12-29 08:12:51

動態規劃profit

2018-01-21 23:14:09

戴爾

2013-05-16 10:07:42

固態硬盤RAID 0三星840 Pro
點贊
收藏

51CTO技術棧公眾號

中文字幕在线视频不卡| 亚洲欧美精品| 色多多视频在线观看| 国产清纯在线一区二区www| 激情久久av| 午夜天堂精品久久久久| 青青在线视频一区二区三区| 精品视频成人| 中文国产亚洲喷潮| a欧美人片人妖| 欧美成人精精品一区二区频| 国内精品一区视频| 亚洲成a天堂v人片| 向日葵污视频在线观看| www久久精品| 18禁免费观看网站| 国产精品一区二区91| 在线码字幕一区| 久久精品国产免费| 亚洲7777| 精品在线你懂的| 亚洲高潮无码久久| 成人在线视频一区二区| 国产免费一区二区视频| 成人免费视频视频在线观看免费| 婷婷视频在线播放| 国产成人av网站| 少妇高潮喷水久久久久久久久久| eeuss鲁片一区二区三区在线观看 eeuss影院一区二区三区 | 91美女片黄在线观| 99久久精品网站| 亚洲综合一区二区不卡| 亚洲激情婷婷| 香蕉视频在线网址| 久久嫩草精品久久久精品一| 欧美日韩亚洲一二三| 亚洲婷婷在线视频| 日本不卡免费播放| 777a∨成人精品桃花网| aa视频在线观看| 久久五月天综合| 欧美精品一区二区久久| 99re国产视频| 激情综合色综合久久| 国产精品亚洲a| 黑人与娇小精品av专区| 国产视频久久久久久久| 欧美三级资源在线| www.99在线| 天天影视网天天综合色在线播放| 色大18成网站www在线观看| 亚洲精品久久久久久久久久久| 国产精品高清在线观看| 亚洲精品福利视频| 日韩免费电影| 欧美精品手机在线| 伊人成综合网yiren22| www.久久久| 韩国v欧美v日本v亚洲v| 亚洲天堂av线| 精品视频在线免费看| 精品欧美一区二区三区在线观看| 欧美激情网友自拍| 自产国语精品视频| 妺妺窝人体色www看人体| 亚洲图片你懂的| www.在线视频.com| 中文字幕欧美日韩va免费视频| 青青草这里只有精品| 国产原创精品| 国产精品99久久久久久宅男| 制服丝袜影音先锋| 欧美色涩在线第一页| 涩涩涩久久久成人精品| 成人欧美一区二区三区在线湿哒哒| 日本中文字幕一区| 7878视频在线观看| 亚洲成人动漫在线播放| 日韩高清影视在线观看| 欧洲精品久久| 综合在线观看色| 免费不卡av| 国产免费一区二区三区在线能观看| 久久青草久久| 校园春色影音先锋| 伊人伊成久久人综合网小说| 欧美日韩国产欧| 成人18免费| 精品五月天久久| 91影院成人| 欧美成人免费高清视频| 欧美成人女星排名| 色综合久久一区二区三区| 日本中文字幕网址| 91精品国产欧美日韩| 欧美日韩精品一区二区视频| 色综合久久久久无码专区| 精品日韩在线观看| 亚洲精品91| 超清福利视频| xxav国产精品美女主播| 久久精品国语| 久青青在线观看视频国产| 久久久免费电影| 国产大陆a不卡| 超碰在线中文字幕| 久久av一区二区| 日韩欧美aⅴ综合网站发布| 久久精品国产亚洲5555| 国产黄色片免费在线观看| 欧美精品一区二区三区一线天视频| 女人香蕉久久**毛片精品| 国产视频资源| 欧美精品成人91久久久久久久| 成人永久aaa| 成人国产二区| 桥本有菜av在线| 日韩一区二区三区电影| 国内激情久久| 暖暖视频在线免费观看| 国产精品久久婷婷六月丁香| 国产精品网曝门| 911亚洲精品| 成人性做爰aaa片免费看不忠| 在线成人一区二区| 成人av综合一区| 日本黄色成人| 国产黄页在线观看| 国产一区二区久久精品| 高清久久久久久| 欧美91在线|欧美| 欧美牲交a欧美牲交aⅴ免费真| 自拍偷拍亚洲一区| 99久久精品免费看国产| 日韩毛片免费看| 色七七在线观看| 国产69久久精品成人| 亚洲精品中文字幕乱码三区| 国内亚洲精品| 欧美r片在线| 成人a视频在线观看| 色综合久久久久网| 99热在线精品观看| 精精国产xxxx视频在线播放| 久久久久久久香蕉| 久久99久久久久久久噜噜| 亚洲国产精品黑人久久久| 看全色黄大色大片免费久久久| 美女一级全黄| 国产区二精品视| 亚洲精品97久久| 91视频com| 欧美日韩一区二区三区视频播放| 欧美一区二区少妇| 牛人盗摄一区二区三区视频| 欧美精品一区二区三区四区| 国产高清精品在线| 欧美男男freegayvideosroom| 免费在线观看麻豆视频 | 黄色网在线看| 操bbb操bbb| 日韩中文字幕av| 亚洲靠逼com| 亚洲成人在线| 黄色成人在线网| 六月婷婷在线视频| 国产ts一区二区| 欧美色精品在线视频| 国精品**一区二区三区在线蜜桃| 日韩毛片免费视频一级特黄| 毛片.com| 色一情一区二区三区四区| 国产午夜精品美女视频明星a级| 国产精品嫩草99a| 亚洲国产影院| 国产精品伊人| 日中文字幕在线| 欧洲金发美女大战黑人| 国产91露脸中文字幕在线| 欧美人体做爰大胆视频| 国产成人av一区二区三区在线 | 亚洲视频碰碰| 一级毛片久久久| 国产成免费视频| 国产免费一区| 伦理中文字幕亚洲| 日本精品视频一区二区| 国产传媒欧美日韩成人| 欧美电影免费观看高清| 中文字幕21页在线看| 91热爆在线观看| 日韩黄色片在线| 91精品天堂| www.久久撸.com| 黄网站色欧美视频| www.日韩大片| 宅男噜噜噜66国产日韩在线观看| 日韩精品视频中文字幕| 性xxxxfjsxxxxx欧美| 男女小视频在线观看|