第七章 遞迴、DFS、剪枝、回溯等問題 ------------- 7.3 題解:機器人走方格問題

Curtis_發表於2019-03-22

機器人走方格

一、問題:

   有一個X*Y的網格,一個機器人只能走格點且只能向右或向下走,要從左上角走到右下角。 請設計一個演算法,計算機器人有多少種走法。 給定兩個正整數int x,int y,請返回機器人的走法數目,保證x+y小於等於12。

二、思路:

  思考這類看起來很複雜的問題,實際上就越有規律可循,我們先列舉一些簡單的情況,再由簡到繁,逐步得出結果,逐步發現規律。就是說先解決簡單情況下的問題,然後再推廣到複雜情況下的問題。就比如這道題目,先假如只有1個格子,那很明顯只有一種走法,那麼我們再去畫 1 * 2,2 * 1,1 * 3,3 * 1,也只有1種走法,再去畫2 * 2 的方格,發現有兩種走法了。

  當我們處於2 * 2的方格的時候我們可以首先往右走一個方格,那麼此時我們處於兩行一列的狀態,我們也可以往下走一個方格那麼我們處於一行兩列的情況那麼1 * 2與2 * 1的走法我們原來是知道的,所以把這兩種走法加起來就得到了2 * 2 方格的走法,也就是兩種走法。

  當我們處於2 * 3的方格的時候我們可以首先往右走一個方格,那麼此時我們處於兩行兩列的狀態,我們也可以往下走一個方格那麼我們處於一行三列的情況那麼2 * 2與1 * 3的情況我們原來是知道的,所以把這兩種走法加起來就得到了2 * 3 方格的走法總共有3種走法,依次類推

  於是我們根據分析就可以得出遞推式f(x , y) = f(x - 1, y) + f(x , y - 1)(因為只能向右走和向下走)

  所以我們可以使用遞迴的方式來解決這個問題,其次我們也可以使用迭代(遞推)的方式來解決,因為涉及到兩個變數都在變化,使用一維的變數是不能夠儲存的,所以要使用二維的資料結構:二維陣列來儲存從起始點到某一點的走法,比如說a[2][3]=3,表示機器人到這一個點總共有3種走法。

  使用遞迴的話就相當於一種富人的思想,把什麼都交給手下人去做,自己只負責合併結果,程式碼很簡潔。而迭代(遞推)相當於打工者的思想,一步步根據自己的分析得出想要的結果,程式碼相對來說比遞迴要複雜一點。

三、程式碼: 

public class 機器人走格子 {

    public static void main(String[] args) {
        System.out.println(solve(3, 3));   // 輸出 6
        System.out.println(solve1(3, 3));  // 輸出 6
    }
    
    /**
     * 遞迴形式
     */
    static int solve(int x,int y){
        if( x==1 || y==1 ) return 1;
        return solve(x-1, y)+solve(x, y-1);
    }
    
    /**
     * 迭代形式
     */
    static int solve1(int m,int n){
        int [][]state = new int[m+1][n+1];
        for (int i = 1; i <= n; i++) {
            state[1][i] = 1;
        }
        for (int i = 1; i <= m; i++) {
            state[i][1] = 1;
        }
        for (int i = 2; i <=m ; i++) {
            for (int j = 2; j <=n ; j++) {
                state[i][j] = state[i][j-1] + state[i-1][j];
            }
        }
        return state[m][n];
    }

}

四、結果:

相關文章