動態規劃基礎 0 1揹包問題

2021-09-25 06:26:59 字數 2790 閱讀 2180

這種揹包問題是最基礎的一類揹包問題。只要掌握的這種,後面的也就是大同小異了。因此,我在這個問題上將講得非常詳細。

0/1揹包問題就是存在乙個揹包有著固定的容積m,物品有自己的質量w和價值c,當然,每乙個物品都只有一件,而且不可拆分。你的任務是:把這些東西裝入這個揹包,使裝入物品的價值最大。

首先,貪心演算法只有在物品可分的時候才會生效(求價效比),搜尋這個指數級的複雜度不解釋!

所以我們選擇動態規劃。

先上**

#include

#include

using namespace std;

const

int maxm=

1005

;int m,n,f[maxm]

;int w[maxm]

,c[maxm]

;int

main()

} cout<

<

return0;

}

樣例輸入

樣例輸出

10 4

122 1

3 34 5

7 9上訴**的第一層for迴圈的目的是控制本次選擇的物品,第二層迴圈在於選擇當前物品時,在揹包體積為j時的最大體積。f[n]表示的就是在揹包體積為n時可以裝下的最大價值。這道題難在這個狀態轉移方程: f [ j ] = m a x ( f [ j ] , f [ j - w [ i ] ] + c [ i ] ) ——這是什麼鬼?i這個變數就相當於是被選擇的這個物品的編號,比如 w [ i ] 就是第 i 個物品的重量。

我們從揹包體積為10開始裝入物品,因為你會發現如果從小體積往大體積裝載,大體積就會受到小體積 f 的影響,因為大的總是拿小的更新自己的 f 值。如果無法理解這句話,就請看模擬吧!

首先我們根據輸入,填入資料。沒錯的話是醬紫:

然後進入第一層for迴圈,選擇了第乙個物品。

我們從第十個開始,也就是 f [ 1 0 ] 開始,填入的資料就是 1 ,因為我們執行了這句話f [ 10 ] = m a x ( f [ 10 ] , f [ 10 - w [ 1 ] ] + c [ 1 ] ) ,這句話的實際意思是:我們要不要拿這個物品,拿了會不會增加揹包體積為10的時候的最大價值,所以我們嘗試著詢問到揹包體積為8時候的最大價值,為什麼不選更小的呢?1號物品的體積剛好是2,所以10減去2空出來的8的體積才有可能是裝下的最大價值。試想,假若現在有乙個物品的質量是1,然後你卻詢問7的,那這個質量為1的豈不是沒裝上去你就算了10的體積,等於我們浪費了乙個體積!而且,你沒事情把他取小掉幹什麼?我們正需要大量的體積來裝更多的物品提公升總價值啊!!!

總之,我們去詢問體積為8的最大價值,其實就是假設我們選了1號物品的意思,所以我們自然也要在後面加上1號物品的價值。然後跟原來的體積為10的比較。誰大就取誰。然後發現f [ 10 - w [ 1 ] ] + c [ 1 ] 是1,f [ 10 ] 是0,取前者。如圖:

然後 j = 9 了,然後發現f [ 9 - w [ 1 ] ] + c [ 1 ] 是1,f [ 9 ] 是0,取前者。,選取第乙個物品走完一輪後,就都是1了。如下圖:

你會問,為什麼第乙個這麼孤單只有0呢?因為,第乙個體積只有1,比物品本身還要小,所以我們就不迴圈啦!反正都是裝不下的。不信你看看第二層迴圈就是這麼寫的:f o r ( i n t j = m ; j > = w [ i ] ; j - - )

接下來第二輪,我們選取了第二個物品啦。還是 j = m 開始迴圈,我們現在揹包體積為10的時候,可以裝下最大價值為1,然而,經過這一步的時候( f [ j ] = m a x ( f [ j ] , f [ j - w [ i ] ] + c [ i ] )),我們發現多了乙個物品,那10的體積還可以繼續裝吧!

所以我們的f [ 10 ] = m a x ( f [ 10 ] , f [ 10 - w [ 2 ] ] + c [ 2 ] )這一步, f [ 10 - w [ 2 ] ] + c [ 2 ] 就是詢問:假如我拿了2號物品,揹包體積為10的時候最大價值會增加嗎?所以假設我們裝了,那剩餘體積就是10 - w [ 2 ]沒錯吧,然後我們看看當前狀態下最大可以裝多少:那就是f [ 10 - w [ 2 ] ] 沒錯吧。但是你總不能佔了我體積又沒有價值吧,所以順理成章把價值也給帶上,那就是 f [ 10 - w [ 2 ] ] + c [ 2 ] ,然後跟原來的f [ 10 ]做乙個比較。發現,我們假設的東西好像還大一點,那就把f [ 10 ]換成我們假設的吧!歡樂~

於是f [ 10 ]就愉快地更新了。

這樣不斷更新下去,第二輪完畢以後就是醬紫:

然後是第三輪完畢以後的效果:

第四輪,也就是最後一輪結束後的效果:

至此,動態規劃結束。直接輸出 f [ 1 0 ] 即可。

動態規劃揹包問題 01揹包

問題描述 n種物品,每種乙個。第i種物品的體積為vi,重量為wi。選一些物品裝到容量為c的揹包,使得揹包內物品不超過c的前提下,重量最大。問題分析 宣告乙個f n c 的陣列。f i j 表示把前i件物品都裝到容量為j的揹包所獲得的最大重量。當 j v i 時,揹包容量不足以放下第 i 件物品,f ...

動態規劃 揹包問題 01揹包

有n種物品和乙個容量為v的揹包,每種物品僅用一次。第i件物品的費用是w i 價值是v i 求解將哪些物品裝入揹包可使價值總和最大。例如 n 5,v 10 重量 價值 第乙個物品 10 5 第二個物品 1 4 第三個物品 2 3 第四個物品 3 2 第五個物品 4 1 首先我們考慮貪心策略,選取最大價...

0 1揹包問題(動態規劃)

一 問題描述 有n件物品和乙個容量為v的揹包。第i件物品的費用是c i 價值是w i 求解將哪些物品裝入揹包可使價值總和最大。所謂01揹包,表示每乙個物品只有乙個,要麼裝入,要麼不裝入。二 解決方案 考慮使用動態規劃求解,定義乙個遞迴式 opt i v 表示前i個物品,在揹包容量大小為v的情況下,最...