有乙個大小為m(整數)的揹包,和n個體積為正整數的物品(大小分別為a[i])。將這個n個物品選一些裝到揹包中,請問最多能裝滿多少的體積?
揹包問題是動態規劃問題的一種典型題目。 動態規劃問題我們一般要考慮下面這四點。
1. 狀態 state
2. 方程 function
3. 初始化 intialization
4. 答案 answer
本題是最基礎的揹包問題,特點是:每種物品僅有一件,可以選擇放或不放,那下面我們來看揹包這題動態規劃的四點是怎麼樣的呢?
1. state: dp[i][s] 表示前i個物品,取出一些能否組成和為s體積的揹包
2. function: f[i][s] = f[i-1][s - a[i]] or f[i-1][s] (a[i]表示第i個物品的大小)
轉移方程想得到f[i][s]前i個物品取出一些物品想組成s體積的揹包。 那麼可以從兩個狀態轉換得到。
(1)f[i-1][s - a[i]] 放入第i個物品,並且前i-1個物品能否取出一些組成和為s-a[i] 體積大小的揹包。
(2)f[i-1][s] 不放入第i個物品, 並且前i-1個物品能否取出一些組成和為s 體積大小的揹包。
3. intialize: f[1...n][0] = true; f[0][1... m] = false
初始化 f[1...n][0] 表示前1...n個物品,取出一些能否組成和為0 大小的揹包始終為真。
其他初始化為假
4. answer: 尋找使f[n][s] 值為true的最大的s. (s的取值範圍1到m)
由於這道題空間上有一些要求,所以在知道了思路答案過後我們還需要進行優化空間複雜度.先考慮上面講的基本思路如何實現,肯定是有乙個主迴圈i=1..n,每次算出來二維陣列f[i][0..s]的所有值。那麼,如果只用乙個陣列f[0..s],能不能保證第i次迴圈結束後f[s]中表示的就是我們定義的狀態f[i][s]呢?f[i][s]是由 f[i-1][s - a[i]] 和 f[i-1][s] 兩個子問題遞推而來,能否保證在推f[i][s]時(也即在第i次主迴圈中推f[s]時)能夠得到 f[i-1][s - a[i]] 和 f[i-1][s] 的值呢?事實上,這要求在每次主迴圈中我們以s=m...0的順序推f[s],這樣才能保證推f[s]時f[s-a[i]]儲存的是狀態f[i-1][s-a[i]]的值。偽**如下:
for i=1..n
for s=m...0
f[s]=f[s] or f[s-a[i]];
九章演算法 微軟面試題 揹包問題 V
給出 n 個物品,以及乙個陣列,nums i 代表第i個物品的大小,保證大小均為正數,正整數 target 表示揹包的大小,找到能填滿揹包的方案數。每乙個物品只能使用一次 樣例 給出候選物品集合 1,2,3,3,7 以及 target 7 結果的集合為 7 1,3,3 返回 2 演算法 dp 動態規...
九章演算法 Google面試題 內積
描述 給定長度為n的a陣列,長度為k的b陣列 你可以從a陣列裡取k個數 規則如下 即每次可以從a陣列的最左邊或者最右邊取走乙個數,取走的數從陣列中移除 將取出的ai按取出的順序組成c陣列 求b與c的內積最大值 b與c內積為 i 0k 1bi ci 解釋1 a 1,4,3,2,5 b 1,2,3,4 ...
九章演算法面試題32 小球排序
有紅黃藍三色的小球若干排成一列,這些小球進行排序,請使用盡量少的空間和時間。假設順序為紅色黃色藍色。用兩根指標從頭開始遍歷,第一根指標遇到非紅色時停下,如果第二根指標找到第一根指標之後的第乙個紅色停下,交換兩根指標所指顏色。重複上述過程。直到第二根指標找不到任何紅色。此時第一根指標到最後都是黃色或藍...