淺談Dynamic Programming
Dynamic Programming(DP) 能帶來的好處是降低時間複雜度,用空間換取時間。
Recursion
一個常見的recursion例子即是費波那契數(Fibonacci number),下方是用recursion來實作的C++
程式:
1 | int fib(n){ |
上方的程式可以藉由下方的樹狀圖表示,這樣透過top-down的方式來解會重複計算數列中的值,大幅增加了計算時間。這樣的方法的時間複雜度為$O(n^2)$,但空間複雜度為$O(1)$。
Dynamic programming(DP)
DP用空間換取時間,它不進行重複的運算,是透過bottom-up的方式將表格建出,也就是依序算出數列中的值,並將計算完的值都儲存起來以供後續查表使用,避免重複計算。
1 | int fib (n) { |
因為計算完的值都會被儲存起來,這樣的方法比
recursion需要更多的記憶體。避免重複計算使得時間複雜度變為$O(n)$,儲存計算完的值使得空間
複雜度為$O(n)$。
DP的4個步驟
Step-1 觀察並找出答案的特徵與結構。e.g.觀察費波那契數為前一個數字以及後一個數字的和。
Step-2 以遞迴方式定義函數。e.g. fib(n)=fib(n-1)+fib(n-2); BC: fib(0)=0, fib(1)=1。
Step-3 建表,用bottom-up的方式依序求解。e.g.
Step-4 利用表格資訊組合出答案。