遞歸到動規的一般轉換方法
遞歸函數有N個參數就定義N維數組,數組的下標就是參數的取值范圍,元素的值就是遞歸函數的返回值,
這樣就可以從邊界值開始逐步填充數組,相當於計算遞歸函數的逆過程。
動規解題的一般思路
1.將原問題分解為子問題
把原問題分解為若干個子問題,子問題和原問題形式相同或者類似,只不過規模變小了,子問題都解決了,原問題即解決。
子問題的解一旦求出,便將其保存,所有每個子問題只需要求解一次。
2.確定狀態
在用動規解題時,我們往往將和子問題相關的各個變量的一組取值,稱之為一個“狀態”。
一個“狀態”對應一個或者多個子問題,所謂某個“狀態”下的值,就是這個“狀態”對應的子問題的解。
所有“狀態”的集合,構成問題的“狀態空間”。“狀態空間”的大小,與用動態規划解決問題的時間復雜
度直接相關。 在數字三角形的例子里,一共有N×(N+1)/2個數字,所以這個問題的狀態空間里一共就有N×(N+1)/2個狀態。
整個問題的時間復雜度是狀態數目乘以計算每個狀態所需時間。在數字三角形里每個“狀態”只需要經過一次,
且在每個狀態上作計算所花的時間都是和N無關的常數。
3.確定一些初始狀態(邊界狀態)的值
以“數字三角形”為例,初始狀態就是底邊數字,值就是底邊數字值。
4. 確定狀態轉移方程
定義出什么是“狀態”,以及在該“狀態”下的“值”后,就要找出不同的狀態之間如何遷移――即如何
從一個或多個“值”已知的 “狀態”,求出另一個“狀態”的“值”(遞推型)。狀態的遷移可以用遞推公式表示,
此遞推公式也可被稱作“狀態轉移方程”。
數字三角形的狀態轉移方程:
能用動規解決的問題的特點
1) 問題具有最優子結構性質。如果問題的最優解所包含的 子問題的解也是最優的,我們就稱該問題具有最優子結 構性質。
2) 無后效性。當前的若干個狀態值一旦確定,則此后過程的演變就只和這若干個狀態的值有關,和之前是采取哪種手段或經過哪條路徑演變到當前的這若干個狀態,沒有關系。
經典例題:
1.數字三角形
2.最長上升子序列
3.最長公共子序列
4.最佳加法表達式