1. 程式人生 > >漫畫:什麼是動態規劃?(整合版)

漫畫:什麼是動態規劃?(整合版)

題目:

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

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

解法1:暴力列舉法(利用排列組合思想,寫一個多層巢狀迴圈遍歷出所有的可能性。每遍歷出一個組合,讓計數器加一)
這裡寫圖片描述
大事化小,小事化了
那剛才的面試題目來說,假設只差最後一步就走到第10級臺階,這時候會出現幾種情況?
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
思路如下
這裡寫圖片描述
F(10) = F(9) + F(8)
這裡寫圖片描述
動態規劃當中包含三個重要的概念:最優子結構,邊界,狀態轉換公式
這裡寫圖片描述
這裡寫圖片描述


這裡寫圖片描述
動態規劃兩個部分:1問題建模,2解決問題
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
備忘錄演算法{}
這裡寫圖片描述
這裡寫圖片描述
程式從 i=3 開始迭代,一直到 i=n 結束。每一次迭代,都會計算出多一級臺階的走法數量。迭代過程中只需保留兩個臨時變數a和b,分別代表了上一次和上上次迭代的結果。 為了便於理解,我引入了temp變數。temp代表了當前迭代的結果值。
題目二: 國王和金礦

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

這裡寫圖片描述
方法一:排列組合

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

程式碼比較簡單就不展示了,時間複雜度也很明顯,就是O(2^N)。
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
第一步:找出最優子結構
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
F(5,10) = MAX( F(4,10) , F(4, 10 - P(4) ) +G【4】 )
第二步:找出最優選擇之間的關係
這裡寫圖片描述
第三步:確定問題的邊界
這裡寫圖片描述
這裡寫圖片描述
方法二:簡單遞迴

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

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

方法三:備忘錄演算法

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

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

這裡寫圖片描述