動態規划系列之一爬樓梯問題


動態規划

官方解釋:
動態規划(Dynamic Programming,DP)是運籌學的一個分支,是求解決策過程最優化的過程。20世紀50年代初,美國數學家貝爾曼(R.Bellman)等人在研究多階段決策過程的優化問題時,提出了著名的最優化原理,從而創立了動態規划。動態規划的應用極其廣泛,包括工程技術、經濟、工業生產、軍事以及自動化控制等領域,並在背包問題、生產經營問題、資金管理問題、資源分配問題、最短路徑問題和復雜系統可靠性問題等中取得了顯著的效果。

動態規划是程序進階路上必須要經過的一個山坡,所以記錄在學習動態規划過程中的方法和思路。

動態規划系列文章一共分為九個部分,每一個部分都是一個獨立的例子,難易程度逐漸遞增。這九個例子分別是:

  1. 動態規划系列之一爬樓梯問題
  2. 動態規划系列之二最大和子數組
  3. 動態規划系列之三乘積最大子數組
  4. 動態規划系列之四梅花樁問題
  5. 動態規划系列之五打家劫舍
  6. 動態規划系列之六01背包問題
  7. 動態規划系列之七完全背包問題
  8. 動態規划系列之八多重背包問題
  9. 動態規划系列之九找零錢

爬樓梯問題

不管問題有多難,我們首先來個望聞問切。以下面這個爬樓梯問題作為開胃菜。請聽題:

有一座高度是10級台階的樓梯,從下往上走,每跨一步只能向上1級或者2級台階。要求用程序來求出一共有多少種走法。比如,每次走1級台階,一共走10步,這是其中一種走法。我們可以簡寫成 1,1,1,1,1,1,1,1,1,1。

那么先不看答案,你覺得這一個問題該如何解決呢?從下往上一步一步的走,for循環嘗試所有的辦法嗎?每一步的走法都會影響后面的走法,所以計算的量非常龐大。那么使用動態規划的解題思路如何處理呢?

動態規划問題的解決方式有幾個固定的套路,個人總結為:

  1. 建立數學模型
  2. 狀態轉移方程
  3. 確立邊界值

第一步 建立數學模型

假設走到第10級台階有f(10)種方法,走到第9級台階有f(9)種方法。記住這里f(10)就是走10級台階走法的數量,這是動態規划的常見數學模型

第二步 狀態轉移方程

走到 10 級台階時前面有兩種可能,一種是從第8級台階走上來,一次跨了2級台階;或者從第9級台階走上來,一次跨了1級台階。所以說 走第10級台階的總數 = 到第9級台階的走法 + 到第8級台階的走法

f(10) = f(9) + f(8)

同樣道理,走到第9級台階時肯定有兩個可能,要么從第7級台階過來,要么從第8級台階過來。所有

f(9) = f(8) + f(7)
f(8) = f(7) + f(6)
f(7) = f(6) + f(5)
.....

總結狀態轉移方程就是:

f(n) = f(n-1) + f(n-2)

第三步 確立邊界值

第1級台階只有一種走法,就是1步跨上去,第2級台階有兩種走法,分別是每次跨一步,兩次;一次跨兩級台階,一次;所以:

f(1) = 1
f(2) = 2

代碼實現

有了以上的理論基礎就可以寫出代碼來實現這個上樓梯問題。

def up(n):
    if n == 1:
        return 1
    if n == 2:
        return 2

    total = up(n-1)  + up(n-2)

    return total

result = up(10)
print('台階的走法為:%d' % result)
台階的走法為:89

換一個思路

以上的思路是一種由上向下的解法思路,從最后一個值不斷向前推導,直到遇到邊界情況。可以換一個思路,從下往上看。走第一步台階只有1種方法,走第二部台階有2種方法,第三步台階可以從第1步跨2級上來,也可以是從第2步跨1級上來。所以:
已知: 邊界情況 f(1) = 1, f(2) = 2 ,並且知道f(3) = f(1) + f(2)
求解:f(10)

def up(n):
    if n == 1:
        return 1

    if n == 2:
        return 2
    
    a = 1
    b = 2
    sum_num = 0
    for i in range(3,n+1):
        # 狀態轉移方程:f(n) = f(n-1) + f(n-2)
        sum_num = a + b
        a = b
        b = sum_num

    return sum_num 

總結

那么到這里就已經完成了走樓梯的解法,從代碼量來看,核心代碼不超過10行,是不是沒有想象的那么難呢?是的,動態規划並不是想象的那么難,只要能領會思路,了解解題套路就暢通無阻啦。
另外可以看到動態規划問題既可以使用迭代解法,也可以使用循環解法。從常見的解題思路來看,循環的方法比較多。那么如果你已經理解了動態規划的建立數學模型 + 狀態轉移 + 確立邊界值,說明本篇就完全掌握了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM