通過“不同路徑”問題思考動態規劃

問題描述:

一個機器人位於一個 m x n 網格的左上角 (起始點在下圖中標記爲“Start” )。
機器人每次只能向下或者向右移動一步。機器人試圖達到網格的右下角(在下圖中標記爲“Finish”)。
問總共有多少條不同的路徑?
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/unique-paths
在這裏插入圖片描述
例如,上圖是一個7 x 3 的網格。有多少可能的路徑?

動態規劃的四個過程

1.劃分狀態,即劃分子問題。

到每個格子的線路,前一步一定是它上面格子(如果存在)或者左邊格子(如果存在)。問題就劃分成了到上面一格和左面一格的線路數。

2.狀態表示,即如何讓計算機理解子問題。

格子這種二維平面恰好可以類比到二維數組,用int[i][j]表示到(i+1, j+1)這個位置可以走的線路數。之所以+1是因爲數組下標從0開始。

3.狀態轉移,即父問題是如何由子問題推導出來的。

根據1的劃分狀態,到每個格子的線路總數量,是到它上面格子(如果存在)和左邊格子(如果存在)的線路數量之和。

int[i][j] = int[i - 1][j] + int[i][j - 1]

4.確定邊界。

左上角第一格爲起點。最上面一排和最左面一排的線路數都是1,只能走直線,其他線路符合3中的狀態轉移方程。int[1][n] = 1, int[n][1] = 1

public static void main(String[] args) {
   Scanner sc = new Scanner(System.in);
   // i表示橫座標,j表示縱座標
   int i = sc.nextInt(), j = sc.nextInt();
   // 使用二維數組表示狀態
   int[][] lines = new int[i][j];
   for (int p = 0; p < i; p++) {
       for (int v = 0; v < j; v++) {
           // 邊界,(0,0)位置表示啓點
           if (p == 0 && v == 0) {
               lines[p][v] = 0;
           }
           // 邊界,(x,0),(0,x)位置在最上面一排或者最左面一排,只有一條直線路徑
           else if (p == 0 || v == 0) {
               lines[p][v] = 1;
           }
           // 狀態轉移方程
           else {
               lines[p][v] = lines[p-1][v] + lines[p][v-1];
           }
           // 每計算一個位置的路徑數,將結果打印一遍,直觀的觀察計算過程
           printMatrix(lines);
       }
   }
   System.out.println("to position i:" + i + " j:" + j + " lines count:" + lines[i - 1][j - 1]);
}

private static void printMatrix(int[][] lines) {
    for (int[] arr : lines) {
        for (int n : arr) {
            System.out.print(n + "\t");
        }
        System.out.println();
    }
    System.out.println("-----------------------");
    try {
        Thread.sleep(500);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章