演算法學習 01揹包問題

2021-09-28 15:35:35 字數 1911 閱讀 2263

**是慕課網的實戰演算法課程——動態規劃

相當於還是求n個物品的組合!

暴力解法:

每一件物品,都可以放進揹包,也可以不放進。複雜度是o( (2^n) * n ), 對於每乙個組合,還要看看對應的總重是多少,看看是不是超過了容量c,從而看價值。

組合方式都可以用遞迴的方式來求解。只是是能不能找到重疊子問題、最優子結構,從而轉換為dp。

設計:狀態:之前狀態都使用乙個引數就解決了問題,通常問題中引數的個數意味著要解決問題需要滿足的約束條件。

這個問題2個約束條件,首先要從n個物品裡選,然後容量要滿足≤c,因此:狀態(函式)是

f(n,c)考慮將n個物品放入容量為c的揹包,使得價值最大。

狀態轉移:f( i,c) = f(i-1,c)

= v(i) + f( i-1, c-w(i) ) 放入後,考慮前面i-1個物品

對於第i個物品到底要放入or不放入揹包,在二者中選乙個max

狀態轉移方程:f(i,c) = max( f(i-1,c), v(i) + f( i-1, c-w(i) ) )

很多動態規劃問題都可以使用類似上面的思想!

寫**:依舊先使用自頂向下,再改造為自底向上

遞迴方式:

class 

knapsack01

public:

int knapsack01(const vector&w, const vector&v, int c )

};

用記憶化搜尋+遞迴:

重疊子問題:index 和c構成了資料對,這樣的資料對在求解過程中同樣的資料對可能求解了多次,為此可以使用記憶化搜尋方式。

由於揹包問題有兩個約束條件,每乙個狀態中被2個變數定義,所以開闢記憶化空間是二維陣列!—— vectormemo(n, vector(c+1, -1));

memo有n行,每一行都是乙個vector,一共有c+1列

private:

vector> memo;

// 用[0,...index]的物品,來填充容積為c的揹包的最大值

int bestvalue(const vector&w, const vector&v, int index, int c)

動態規劃:

}01揹包的變種:

完全揹包問題:每個物品可以無限使用~

(雖然每個物品可以無限使用,但是揹包容量有限,所以其實每個物品可以取到的個數是有最大值的!

===>所以把無限使用的物品揹包問題轉換為有點使用物品的揹包問題~, 只是在選取的物品列表中有很多物品是重複的)

優化方案:(對於揹包容積很大的時候很好的優化思路)對於任何乙個數字而言,都可以用乙個二進位製碼來表示,所以對於同乙個物品,不一定向列表中新增1,而是新增1 2 4 8 16這樣的序列,表示同乙個物品取了多少個。

多重揹包:每個物品不止乙個,有num(i)個

多重揹包是更簡單的

演算法學習 01揹包(動規)

貪心之後來動規啦 看 演算法導論 感覺還是不那麼清楚,還是得自己動手才行 真正寫的時候發現還是沒有真正理解動規的自底向上的求解方法,又看了幾篇博文,才初步了解了01揹包的真正的執行過程。必須推薦一下參考的文章,也記錄一下,以便日後進一步學習 不說了,上 0 1揹包問題 include using n...

演算法學習 分組揹包問題

有n件物品和乙個容量為v的揹包,第i件物品的重量為w i 價值為v i 這些物品被劃分成了若干組,每組中的物品互相衝突,最多選一件 問將哪些物品放入揹包中可以使揹包獲得最大的價值 對於每一組的物品,都可以看成是乙個01揹包問題,對每組的物品都處理一遍即可。輸入格式 第一行 三個整數,v 揹包容量,v...

演算法(揹包問題 01揹包問題)

01揹包問題 有 n 件物品和乙個容量是 v 的揹包。每件物品只能使用一次。第 i 件物品的體積是 vi,價值是 wi。求解將哪些物品裝入揹包,可使這些物品的總體積不超過揹包容量,且總價值最大。輸出最大價值。輸入格式 第一行兩個整數,n,v,用空格隔開,分別表示物品數量和揹包容積。接下來有 n 行,...