1. 程式人生 > >LintCode UniquePaths 不同的路徑

LintCode UniquePaths 不同的路徑

中文描述:
有一個機器人的位於一個M×N個網格左上角(下圖中標記為’Start’)。
機器人每一時刻只能向下或者向右移動一步。機器人試圖達到網格的右下角(下圖中標記為’Finish’)。
問有多少條不同的路徑?

start 1.2 1.3 1.4 1.5 1.6 1.7
2.1
3.1 3.2 3.3 3.4 3.5 3.6 end

法一:數學公式法
機器人一共要走m+n-2步。
我們要從這m+n-2步中挑出m-1步向下走,或者挑出n-1步向右走。
由於挑出的步數順序唯一,即不必考慮每步之間順序,即應使用組合方法而非排列方法。
數序公式為C((m+n-2),(m-1)) = C((m+n-2),(n-1))
注意:計算階乘可能會超出int甚至long的表達範圍。

法二:動態規劃方法
第一步:

1 1 1 1 1 1 1

第二步:

1 1 1 1 1 1 1
1 2 3 4 5 6 7

第三步:

1 1 1 1 1 1 1
1 2 3 4 5 6 7
1 3 6 10 15 21 28

如果是二維陣列則
dp[i][j] = dp[i-1][j] + dp[i][j-1]
可以看出每一行只使用一次,考慮是否可以重複使用一行,發現可行。
dp[j] = dp[j] + dp[j-1]

public class Solution {
    /**
     * @param n, m: positive integer (1 <= n ,m <= 100)
     * @return an integer
     */
    //法一:計算式m--;n--;求C(m+n,n) = (m+n)!/(m!n!)
    public int uniquePaths(int m, int n) {
        if(m == 1 || n == 1) return 1;
        m--; n--;
        long factorial = 1;
        for
(int i = 1; i <= n; i++) { factorial = factorial*(m + i)/i; } return (int)factorial; } //法二:動態規劃 public int uniquePaths(int m, int n) { int dp[] = new int[n]; for(int i = 0; i < n; i++) { dp[i] = 1; } for(int i = 1; i < m; i++) { for(int j = 1; j < n; j++) { dp[j] += dp[j-1]; } } return dp[n-1]; } }