1. 程式人生 > >走臺階問題的動態規劃

走臺階問題的動態規劃

題目要求:有一座高度為10級臺階的樓梯,從下往上走,每跨一步只能向上1級或者2級臺階。要求用程式來求出一共有多少種走法?
比如,每次走1級臺階,一共走10步,這是其中一種走法,我們可以簡寫成1,1,1,1,1, 1,1,1,1,1。、
  這是一道典型的動態規劃類題目。我們很容易想到,當站在第10個臺階時,會回想剛才最後一步是咋上來的,無外乎兩種方式:一種是在第9個臺階上,然後輕鬆一步到第10個臺階;一種是在第8個臺階上,直接跨了兩個臺階,一步到第10個臺階。
  然後繼續想要知道如何上到第9個或者第8個臺階呢?還是和前面思路一樣,分成一次走1步和一次走2步。。。就這樣層層遞迴,直到走到第1層和第0層臺階為止。所以:
number(走到第10個臺階)= number(走到第9個臺階) + number(走到第8個臺階)

對於這個公式,有一個很自然的想法,走的方法重複了?????


其實,並沒有,儘管走到第9個臺階的方法中,確實包含有走到第8個臺階的方法,但是由於登上第10階的最後一步不一樣,所以從整個過程來看,number(走到第9個臺階) 和 number(走到第8個臺階)還是不一樣的。這也就是說,按照一次走幾步類分類,可以把解集合無重疊、無混淆的分為兩個子集。

下面是自頂向下的遞迴實現,維護了一個HashMap來降低了時間複雜度

package others;

import java.util.HashMap;

public class StepProblem {
    public static void main(String[] args) {
        int
n = 10; HashMap<Integer, Integer> h = new HashMap<Integer, Integer>(); int number1 = step(n, h); int number2 = step(n); System.out.println("number1= " + number1 + " number2= " + number2); } //方法一:自頂向下 private static int step(int n, HashMap<Integer, Integer> h) { // TODO Auto-generated method stub
if(n == 0) { return 1; } if( n < 0) { return 0; } if(h.containsKey(n)) { return h.get(n); } else { int value = step(n - 1, h) + step(n - 2, h); h.put(n, value); return value; } } //方法二,自底向上 private static int step(int n) { int a = 1; int b = 2; int temp = 0; for(int i = 3; i <= n; i++) { temp = a + b; a = b; b = temp; } return temp; } }

逆轉思維,從底部向上,程式碼效率更高!