「每日算法」什麼是動態規劃

點擊上方"java全棧技術"關注,每天學習一個java知識點

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

————————————

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

題目:

有一座高度是10級臺階的樓梯,從下往上走,每跨一步只能向上1級或者2級臺階。要求用程序來求出一共有多少種走法。

比如,每次走1級臺階,一共走10步,這是其中一種走法。我們可以簡寫成 1,1,1,1,1,1,1,1,1,1。

「每日算法」什麼是動態規劃

再比如,每次走2級臺階,一共走5步,這是另一種走法。我們可以簡寫成 2,2,2,2,2。

「每日算法」什麼是動態規劃

當然,除此之外,還有很多很多種走法。

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

————————————

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

第一種情況:

「每日算法」什麼是動態規劃

第二種情況:

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

把思路畫出來,就是這樣子:

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

F(1) = 1;

F(2) = 2;

F(n) = F(n-1)+F(n-2)(n>=3)

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

方法一:遞歸求解

「每日算法」什麼是動態規劃

由於代碼比較簡單,這裡就不做過多解釋了。

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

如圖所示,相同的顏色代表了方法被傳入相同的參數。

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

方法二:備忘錄算法

「每日算法」什麼是動態規劃

在以上代碼中,集合map是一個備忘錄。當每次需要計算F(N)的時候,會首先從map中尋找匹配元素。如果map中存在,就直接返回結果,如果map中不存在,就計算出結果,存入備忘錄中。

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

方法三:動態規劃求解

「每日算法」什麼是動態規劃

程序從 i=3 開始迭代,一直到 i=n 結束。每一次迭代,都會計算出多一級臺階的走法數量。迭代過程中只需保留兩個臨時變量a和b,分別代表了上一次和上上次迭代的結果。 為了便於理解,我引入了temp變量。temp代表了當前迭代的結果值。

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

題目二: 國王和金礦

有一個國家發現了5座金礦,每座金礦的黃金儲量不同,需要參與挖掘的工人數也不同。參與挖礦工人的總數是10人。每座金礦要麼全挖,要麼不挖,不能派出一半人挖取一半金礦。要求用程序求解出,要想得到儘可能多的黃金,應該選擇挖取哪幾座金礦?

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

方法一:排列組合

每一座金礦都有挖與不挖兩種選擇,如果有N座金礦,排列組合起來就有2^N種選擇。對所有可能性做遍歷,排除那些使用工人數超過10的選擇,在剩下的選擇裡找出獲得金幣數最多的選擇。

代碼比較簡單就不展示了,時間複雜度也很明顯,就是O(2^N)。

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

F(n,w) = 0 (n<=1, w

F(n,w) = g[0] (n==1, w>=p[0]);

F(n,w) = F(n-1,w) (n>1, w

F(n,w) = max(F(n-1,w), F(n-1,w-p[n-1])+g[n-1]) (n>1, w>=p[n-1])

其中第三條是補充上去的,原因不難理解。

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

方法二:簡單遞歸

把狀態轉移方程式翻譯成遞歸程序,遞歸的結束的條件就是方程式當中的邊界。因為每個狀態有兩個最優子結構,所以遞歸的執行流程類似於一顆高度為N的二叉樹。

方法的時間複雜度是O(2^N)。

方法三:備忘錄算法

在簡單遞歸的基礎上增加一個HashMap備忘錄,用來存儲中間結果。HashMap的Key是一個包含金礦數N和工人數W的對象,Value是最優選擇獲得的黃金數。

方法的時間複雜度和空間複雜度相同,都等同於備忘錄中不同Key的數量。

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

方法四:動態規劃

「每日算法」什麼是動態規劃

方法利用兩層迭代,來逐步推導出最終結果。在外層的每一次迭代,也就是對錶格每一行的迭代過程中,都會保留上一行的結果數組 preResults,並循環計算當前行的結果數組results。

方法的時間複雜度是 O(n * w),空間複雜度是(w)。需要注意的是,當金礦只有5座的時候,動態規劃的性能優勢還沒有體現出來。當金礦有10座,甚至更多的時候,動態規劃就明顯具備了優勢。

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

「每日算法」什麼是動態規劃

文章摘自程序員小灰


分享到:


相關文章: