最簡單的動態規劃題,木有之一
阿新 • • 發佈:2019-01-01
動態規劃英文名為dynamic programming,其中pogramming指的是表格法,而非編寫計算機程式。
基本原理
動態規劃將問題分成若干個相互重疊的子問題,遞迴的求解子問題,儲存子問題的解,再將它們的解組合起來,求出原問題的解。實際操作中,記錄下子問題的結果,儲存在一個表格中,使得公共的子問題只需要計算一次。
最優子結構
問題的最優解由相關子問題的最優解組合而成,一個問題的最優解包含其子問題的最優解。
總結
- 滿足“最優子結構”性質的問題才能用動態規劃法來解;
- 寫出狀態轉移方程和邊界條件,則問題得解;
題目
下面是一個最簡單的動態規劃小題目,沒有之一。
有一座高度是10級臺階的樓梯,從下往上走,每跨一步只能向上1級或者2級臺階。求一共有多少種走法。
思考過程
當只剩最後一步就上到10級的時候,有幾種情況呢?
兩種:走了9級了 和 走了8級了
因此,狀態轉移方程是
F(n) = F(n-1) + F(n-2)
而邊界條件呢?
F(1) = 1
F(2) = 2
開始程式設計
方法-1 簡單遞迴
做了許多重複計算,時間複雜度太高,達到O(2^N)
方法-2 遞迴+快取
不再做重複計算,時間複雜度只有O(N)了,而空間複雜度也是O(N)
cache = dict() def f(n): if n < 1: return 0 if n in [1,2]: return n if cache.get(n) is not None: return cache[n] else: result = f(n-1) + f(n-2) cache[n] = result return result print(f(100))
方法-3 自底向上迭代法
時間複雜度還是O(N), 空間複雜度只有O(1)
int climbing_ways(int n)
{
if (n<1) return 0;
if (n==1 || n==2) return n;
int a=1, b=1, temp=0;
for(int i=3; i<=n; ++i) {
temp = a + b;
a = b;
b = temp;
}
return temp;
}
(完)