通過把原問題分解為相對簡單的子問題的方式求解複雜問題的方法。動態規劃常常適用於有重疊子問題和最優子結構性質的問題。
若要解乙個給定問題,我們需要解其不同部分(即子問題),再合併子問題的解以得出原問題的解。 通常許多子問題非常相似,為此動態規劃法試圖僅僅解決每個子問題一次,從而減少計算量: 一旦某個給定子問題的解已經算出,則將其記憶化儲存,以便下次需要同乙個子問題解之時直接查表。 這種做法在重複子問題的數目關於輸入的規模呈指數增長時特別有用。
1>最優子結構
2>邊界
3>狀態轉移公式
題目:
有一座高度是10級台階的樓梯,從下往上走,每跨一步只能向上1級或者2級台階。要求用程式來求出一共有多少種走法。
比如,每次走1級台階,一共走10步,這是其中一種走法。我們可以簡寫成 1,1,1,1,1,1,1,1,1,1。
思路分析:
首先,我們先想乙個問題,如果只差最後一步有幾種到達10層的方法
9 + 1
8 + 2
一種是從8層去十層,一種是九層到十層。
那麼f(10) = f(9)+f(8);
遞迴過去
f(9) = f(8)+f(7)….
f(9),f(8)就是f(10)的最優子結構
f(1) = 1 ,f(2) = 2就是邊界
f(n) = f(n-1)+f(n-2)就是狀態轉移方程
所以得到第一種寫法:
public
static
intgetways(int n)
if(n == 1)
if(n == 2)
return getways(n-1) + getways(n-2);
}
但是這樣的遞迴關係有重複的步驟。
可以用乙個hashmap來記重
於是有了第二種寫法:
public
static
intgetways(int n,hashmapmap)
if(n == 1)
if(n == 2)
if(map.containskey(n)) else
}
然後思路反轉,既然能遞迴,那麼我們能不能從f(1)迭代到f(10)呢?
第三種方法:
public
static
intgetways(int n)
if(n == 1)
if(n == 2)
int a = 1;
int b = 2;
int temp = 0;
for(int i = 3;i <=n; i++)
return temp;
}
這樣的時間複雜度只有o(n),顯然更加好。 動態規劃 爬樓梯
假設你正在爬樓梯,需要n步你才能到達頂部。但每次你只能爬一步或者兩步,你能有多少種不同的方法爬到樓頂部?比如n 3,1 1 1 1 2 2 1 3,共有3種不同的方法 返回 3 解題思路 沒接觸過動態規劃的時候,我用排列組合做的,在我這篇部落格中 可以看一下。實際上,這個題目就是乙個斐波那契數列,這...
爬樓梯 動態規劃
假設你正在爬樓梯。需要 n 階你才能到達樓頂。每次你可以爬 1 或 2 個台階。你有多少種不同的方法可以爬到樓頂呢?注意 給定 n 是乙個正整數。示例 1 輸入 2 輸出 2 解釋 有兩種方法可以爬到樓頂。1.1 階 1 階 2.2 階 示例 2 輸入 3 輸出 3 解釋 有三種方法可以爬到樓頂。1...
動態規劃 爬樓梯
假設你正在爬樓梯。需要 n 階你才能到達樓頂。每次你可以爬 1 或 2 個台階。你有多少種不同的方法可以爬到樓頂呢?注意 給定 n 是乙個正整數。示例 1 輸入 2 輸出 2 解釋 有兩種方法可以爬到樓頂。1.1 階 1 階 2.2 階 示例 2 輸入 3 輸出 3 解釋 有三種方法可以爬到樓頂。1...