1. 程式人生 > >01揹包問題吐血詳解

01揹包問題吐血詳解

揹包問題我真是學一次忘一次,很多dp問題也是由這個衍生而來,今天終於痛下決心寫個部落格供自己日後參考

問題描述:

有N件物品和一個容量為V的揹包。第i件物品的費用是c[i],價值是w[i]。求解將哪些物品裝入揹包可使價值總和最大。

基本思路 :
這是最基礎的揹包問題,特點是:每種物品僅有一件,可以選擇放或不放。 用子問題定義狀態:即f[i][v]表示前i件物品恰放入一個容量為v的揹包可以獲得的最大價值。則其狀態轉移方程便是:tab[i][j] = max(tab[i-1][j-weight[i]]+value[i],tab[i-1][j]) ({i,j|0<i<=n,0<=j<=total})


其中i表示放第i個物品,j表示揹包所容納的重量,那麼tab[i-1][j-weight[i]]+value[i]表示放入第i物品,剛開始接觸會有疑問,tab[i-1][j-weight[i]]這個值,可以這樣理解:tab[i-1][j]為裝到上一個物品在揹包j容量時的最佳值,那麼如果我要求在j容量的時候放入現在的i物品的價值,那麼是不是要先得到容量為(j-weight[i])時候的價值,即先得到 tab[i-1][j-weight[i]] 所以 tab[i-1][j-weight[i]]+value[i] 為放入第i物品的價值; tab[i-1][j] 就是不放入第i個物品。

例子:5個物品,(重量,價值)分別為:(5,12),(4,3),(7,10),(2,3),(6,6)。

揹包容量

0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

5物品

0

0

0

0

0

0

6

12

12

15

15

18

22

22

25

25

4物品

0

0

3

3

3

3

3

12

12

15

15

18

22

22

25

25

3物品

0

0

0

0

0

0

0

12

12

15

15

15

22

22

22

22

2物品

0

0

0

0

3

12

12

12

12

15

15

15

15

15

15

15

1物品

0

0

0

0

0

12

12

12

12

12

12

12

12

12

12

12

for(int i = 1; i <= n; i++)
    {
        for(int j = 0; j <= W; j++)
        {
            if(j < w[i])    dp[i][j]  = dp[i-1][j];
            else dp[i][j] =  max(dp[i-1][j], dp[i-1][j - w[i]] + v[i]);
        }
    }

優化空間複雜度:
以上方法的時間和空間複雜度均為O(VN),其中時間複雜度應該已經不能再優化了,但空間複雜度卻可以優化到O(V)

先考慮上面講的基本思路如何實現,肯定是有一個主迴圈i=1..N,每次算出來二維陣列f[i][0..V]的所有值。那麼,如果只用一個數組f[0..V],能不能保證第i次迴圈結束後f[v]中表示的就是我們定義的狀態f[i][v]呢?f[i][v]是由f[i-1][v]和f[i-1][v-c[i]]兩個子問題遞推而來,能否保證在推f[i][v]時(也即在第i次主迴圈中推f[v]時)能夠得到f[i-1][v]和f[i-1][v-c[i]]的值呢?事實上,這要求在每次主迴圈中我們以v=V..0的順序推f[v],這樣才能保證推f[v]時f[v-c[i]]儲存的是狀態f[i-1][v-c[i]]的值。如果將v的迴圈順序從上面的逆序改成順序的話,那麼則成了f[i][v]由f[i][v-c[i]]推知,與本題意不符,但它卻是另一個重要的揹包問題P02最簡捷的解決方案,故學習只用一維陣列解01揹包問題是十分必要的。

 虛擬碼如下:

for i=1..N

for v=V..0

f[v]=max{f[v],f[v-c[i]]+w[i]};

畫個圖給大家演示下

也就是說此時的f[v],f[v-c[i]]是前面的

假設體積是10  

揹包體積----->>>>>

價值

大小

1

2

3

4

5

6

7

8

9

10

2

1

2

2

2

2

2

2

2

2

2

2

1

2

2

2

3

3

3

3

3

3

3

3

5

3

2

2

3

3

3

8

8

8

8

8

4

4

2

2

3

3

3

相關推薦

01揹包問題(轉載)

這個學期開的演算法設計與分析課程老師說是研究生才要學的課,但是我們大二就要學! 雖然有難度,但還是要學滴。 上機課題目有一道0-1揹包的問題,上課的時候由於沒有聽課。。所以只有自己再啃書本了。 程式碼雖然不長,但是還是。。很有。。技術含量的。 本人文筆不是很好,所以就 不多說啦!直接上菜! 問題描述: 給定

01揹包問題

  首先非常感謝劉汝佳的小白書、HDU劉春英老師的ACM程式設計揹包演算法課件以及dd_engi的揹包九講和眾多大神的部落格,看這麼多資料最後花了整整一天時間才算大致弄懂了揹包問題的思路(=_=搞這麼久我確實有點笨=_=)。OK,接下來就大致講一下我所理解的揹包問題,對這些

01揹包問題吐血

揹包問題我真是學一次忘一次,很多dp問題也是由這個衍生而來,今天終於痛下決心寫個部落格供自己日後參考 問題描述: 有N件物品和一個容量為V的揹包。第i件物品的費用是c[i],價值是w[i]。求解將哪些物品裝入揹包可使價值總和最大。 基本思路 : 這是最基礎的揹包問題,特點是

揹包問題01揹包、完全揹包、多重揹包

參考連結: 揹包問題是動態規劃演算法的一個典型例項,首先介紹動態規劃演算法: 動態規劃: 基本思想: 動態規劃演算法通常用於求解具有某種最優性質的問題。在這類問題中, 可能會有很多可行解。沒一個解都對應於一個值,我們希望找到具有最優值的解。胎動規

動態規劃之01背包

題解 for 可見 round 往裏面 原創 ble -a eight 先看問題: 有N件物品和一個容量為V的背包。(每種物品均只有一件)第i件物品的費用是c[i],價值是w[i]。求解將哪些物品裝入背包可使價值總和最大。 通過閱讀問題,因為背包就是要往裏面放東西,所以一件

01-struts2配置

調試 dev efault nbsp config patch 錯誤 public include 1 struts.xml配置詳解 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts P

01-spring配置

eth height 直接 arr work ssp creat exp context 1 bean元素 <!--將User對象交給spring容器進行管理 --> <!-- Bean元素:使用該元素描述需要spring容器管理的對象

FFMPEG進階系列01-ffplay命令

概述 ffplay是一個基於FFMPEG庫和SDL庫開發的多媒體播放器。它的主要目的是是用來測試FFMPEG的各種API,比如codec/format/filter等等庫。 掌握ffplay的設計邏輯,對於播放器開發人員提升經驗非常有幫助。嗶哩嗶哩的ijkplayer就是基於ffplay做的二次開

01、Synchronized

1. synchronized簡介 在學習知識前,我們先來看一個現象: public class SynchronizedDemo implements Runnable { private static int count = 0; public static void

動態規劃法解決0/1揹包問題

是什麼          動態規劃(dynamic programming)是求解決策過程最優化的數學方法,把多階段過程轉換為一系列單階段問題,利用各階段之間的關係,逐個求解,創立了解決這類過程優化問

各種揹包問題

P01: 01揹包問題 題目 有N件物品和一個容量為V的揹包。第i件物品的費用是c[i],價值是w[i]。求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,且價值總和最大。 基本思路 這是最基礎的揹包問題,特點是:每種物品僅有一件,可以選擇放或不放。

01揹包

01揹包 給定一個容量為c的揹包,有n個物品,第i個質量為wi,價值為vi,求揹包的最大價值 由於每種物品只有1個,因此每個物品只有01兩種狀態,即拿和不拿 用V【i,j】表示在面對第i個物品且揹包容量

01揹包的四種解法:動態規劃,貪心法,回溯法,優先佇列式分支限界法(C語言編寫)

最近剛完成了演算法課程設計,題目是用多種解法解決01揹包問題,經過一番探索,終於成功的用四種方法完成了本次實驗,下面記錄分享一下成果: 首先解釋下什麼是01揹包問題:給定一組共n個物品,每種物品都有自己的重量wi, i=1~n和價值vi, i=1~n,在限定的總重量(揹包的

揹包問題——“01揹包及實現(包含揹包中具體物品的求解)

-----Edit by ZhuSenlin HDU          01揹包是在M件物品取出若干件放在空間為W的揹包裡,每件物品的體積為C1,C2,…,Cn,與之相對應的價值為W1,W2,…,Wn.求解將那些物品裝入揹包可使總價值最大。         動態規劃(DP)

01,完全,多重揹包

揹包問題泛指以下這一種問題: 給定一組有固定價值和固定重量的物品,以及一個已知最大承重量的揹包,求在不超過揹包最大承重量的前提下,能放進揹包裡面的物品的最大總價值。 這一類問題是典型的使用動態規劃解決的問題,我們可以把揹包問題分成3種不同的子問題:0-1揹包問題、完全揹包和多重揹包問題。下面對這三種問題分別進

Java虛擬機01----初識JVM

日誌 可變 lar 反射 開始 rac ibm java語言 lan 主要內容如下: JVM的概念 JVM發展歷史 JVM種類 Java語言規範 JVM規範 一、JVM的概念: JVM:   Java Virtual Machine,意為Java虛擬機。 虛擬機:   

【iOS】第01講 UIView/UIViewController/UIApplication

一、UIView詳解 Command+Alt+Enter -> 顯示ViewController 按住Ctrl直接把UIView拖到ViewController  1.1 UIView的常見屬性  @property(nonatomic,reado

利用動態規劃演算法01揹包問題->二維陣列傳參->cpp記憶體管理->堆和棧的區別->常見的記憶體錯誤及其對策->指標和陣列的區別->32位系統是4G

1、利用動態規劃演算法解01揹包問題 https://www.cnblogs.com/Christal-R/p/Dynamic_programming.html 兩層for迴圈,依次考察當前石塊是否能放入揹包。如果能,則考察放入該石塊是否會得到當前揹包尺寸的最優解。 // 01 knap

keras之ImageDataGenerator引數及用法例項-01

keras圖片生成器ImageDataGenerator keras.preprocessing.image.ImageDataGenerator(featurewise_center=False,     samplewise_center=False,   &nbs