題意:
某farmer最近買了乙個書架,但是由於書架太高,farmer夠不到書架的頂端,現在屌絲farmer開始通過將自己牧場的牛累起來這樣使所累起來的牛能夠高於書架的高度,但是努力使壘起來的牛的高度比書架的高度盡量能達到最小,求這個最小值。
解題思路:
初次看到這個題的時候真心的不知道怎麼解,雖然感覺和揹包有千絲萬縷的關係,但是卻不知道怎麼轉換,總是感覺變化了好像就變味了,知道瞥了眼解題報告,瞬間豁然開朗,柳暗花明。。。
其實就是將所有牛的高度加起來,與書架的高度做差得到v,這樣再將v作為揹包的體積,然後在轉化為01揹包就好了,此處注意在這裡沒有價值這個變數,所以在迴圈的時候,將體積作為價值就好了,這樣的話裝完後其實簡單的要命,只不過當時沒有轉化過來,這可能是這道題的精髓吧
**:
#include #include #include using namespace std;
int main()
v=sum-v1;
//cout<
}cout我們看到的求最優解的揹包問題題目中,事實上有兩種不太相同的問法。有的題目要求
「恰好裝滿揹包
」時的最優解,有的題目則並沒有要求必須把揹包裝滿。一種區別這兩種問法的實現方法是在初始化的時候有所不同。
如果是第一種問法,要求恰好裝滿揹包,那麼在初始化時除了
f[0]為0
其它f[1..v]
均設為-∞
,這樣就可以保證最終得到的
f[n]
是一種恰好裝滿揹包的最優解。
如果並沒有要求必須把揹包裝滿,而是只希望**盡量大,初始化時應該將
f[0..v]
全部設為0。
為什麼呢?可以這樣理解:初始化的
f陣列事實上就是在沒有任何物品可以放入揹包時的合法狀態
。如果要求揹包恰好裝滿,那麼此時只有容量為
0的揹包可能被價值為0的
nothing「
恰好裝滿
」,其它容量的揹包均沒有合法的解,屬於未定義的狀態,它們的值就都應該是
-∞
了。如果揹包並非必須被裝滿,那麼任何容量的揹包都有乙個合法解
「什麼都不裝
」,這個解的價值為
0,所以初始時狀態的值也就全部為0了。
這個小技巧完全可以推廣到其它型別的揹包問題,後面也就不再對進行狀態轉移之前的初始化進行講解。 小結
01揹包問題是最基本的揹包問題,它包含了揹包問題中設計狀態、方程的最基本思想,另外,別的型別的揹包問題往往也可以轉換成
01揹包問題求解。故一定要仔細體會上面基本思路的得出方法,狀態轉移方程的意義,以及最後怎樣優化的空間複雜度。
對於此類經典的01揹包,為了和完全揹包區別開來,簡單的看是不夠的,並且很難想出其**的區別和本質區別,下面就通過實際的數值來區分(其實**的本質區別就是01揹包從體積大的開始遍歷,這樣的話就不能一件物品多次放置,而完全揹包就不同了,是從體積最小的開始遍歷,這樣的話就會出現一件物品多次放置的特點,這樣也就凸顯了兩種揹包的不同,但是這兩種都是最基本的揹包雛形)
假設測試用例:
物品編號
0
1
2
3
4 體積
3 45
6 7
價值 5
6 78 9
01揹包執行過程:
完全揹包執行過程:
具體完全揹包案例: piggy-bank (完全揹包)
0 1揹包與完全揹包
現有 n 件物品,乙個最大容量為 w 的揹包。第 i 件物品重量為 wi 價值為 vi 已知對於一件物品,你必須選擇取或不取,且每件物品只能被取一次 這就是 0 1 的含義 求放置哪幾件物品進揹包,使得揹包中物品價值最大 或是求最大價值是多少等衍生問題 設 ans n,w 為當揹包容重量為 w 有 ...
揹包問題 01揹包與完全揹包
一 介紹 揹包問題是最廣為人知的動態規劃問題,都是給定限定的揹包容量與物品,求所能裝下的最大價值 完全揹包 有n種物品,每種均有無限多,第i種物品額體積為v i 重量 價值 為w i 01揹包 有n種物品,每種只有乙個,第i種物品額體積為v i 重量 價值 為w i 在揹包問題中,我們把不同種的物品...
01揹包,完全揹包
動態規劃 動態規劃的核心是狀態以及狀態轉移方程。需要定義乙個 i,j 狀態以及該狀態的指標函式d i,j 01揹包 有n種物品,每種只有乙個,第i件物品的體積為vi質量為wi。選一些物品裝到體積為c的揹包中,使其體積不超過c的前提下重量最大。namevw abcd e 子問題定義 dp i j 表示...