遞歸和動態規劃的轉換

最近重新研讀了下《挑戰程序設計》對動態規劃和遞歸的關係有了點新的理解,之前的理解過於機械化,單純的以爲根據遞推公式可以直接寫DP代碼。

通俗的來說,

遞歸 是  考慮所有的情況,一般使用搜索(DFS /BFS)來實現。

在那些 可以轉換爲 DP 的遞歸算法中, 必定有很多重複的情況。

比如要做以下算術

1 + 1

1 + 1 + 1

2 + 1 + 1

3 + 1 + 1  

那麼如果用遍歷思維,也是符合人類習慣的思維之一,我們會:

1+1=2

1 + 1 =2  ;  2+1 =3

2 + 1 =3 ;  3+1 =4 ; 

3 + 1=4; 4+1 =5;  

共 7次。

而如果我們聰明點的話,我們可以把一些已經計算的過程記錄下來

1+1 =2               =>                   add[1][1]= 2

add[1][1] =2     ;    2 +1 =3    =>           add[2][1] =3

add[2][1]=3  ;  3+1 = 4 =>  add[3][1] =4;

add[3][1] =4; 4+1=5  =>  add[4] [1] =5 ;

共 4次運算。因爲add[][]是一個數字,可以直接返回。

可能 加法運算讓大家感覺不到優勢在哪裏, 如果 把  + 號  當作是一個 很複雜的運算, 那麼這種優化就十分有價值了。


這種優化方法 叫做  記憶化搜索 方法。

這種方法和 遞歸 剪枝  有本質的區別, 剪枝 法是把那些根本不可能的分枝去掉,而沒有 對 遍歷過程中存在的循環去掉,所以計算量等級上沒有變化。

使用了 記憶化搜索 優化的遞歸算法,其時間複雜度 和  轉換後的DP算法是一致的。


所以我們有以下定義成立:


一般可以使用記憶化搜索進行優化的遞歸算法,我們可以使用DP來進行優化。


至於如何公式化的,通用化的把 遞歸轉變爲 DP,還需要繼續理解理解。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章