动态规划——坐标型
坐標(biāo)型
目錄
1. 矩陣的總路徑數(shù)
1. 題目描述
給定m行n列的網(wǎng)格,有一個(gè)機(jī)器人從左上角(0,0)出發(fā),每一步可以向下或者向右走一步,問有多少種不同的方式走到右下角
2. 思路
確定狀態(tài)
1. 設(shè)右下角坐標(biāo)為(m-1, n-1),那么機(jī)器人一定是從(m-1, n-2)或者(m-2, n-1)走過來的
2. 那么,如果機(jī)器人有X種方式從左上角走到(m-1,n-2),有Y種方式走到(m-2,n-1),則機(jī)器人有X+Y種方式走到(m-1,n-1)
3. 那么問題轉(zhuǎn)化為機(jī)器人有多少種方式從左上角走到(m-1,n-2)和(m-2,n-1)
轉(zhuǎn)移方程
f[i][j] = f[i][j-1] + f[i-1][j]
初始條件和邊界情況
1. 初始條件:f[0][0] = 1,因?yàn)橹挥幸环N方式到左上角
2. 邊界情況:i=0 或 j=0,則前一步只能有一個(gè)方向過來,f[i][j]=1
計(jì)算順序
f[0][0] = 1
計(jì)算第0行:f[0][0], f[0][1], …, f[0][n-1]
計(jì)算第1行: f[1][0], f[1][1], …, f[1][n-1]
…
計(jì)算第m-1行: f[m-1][0], f[m-1][1], …, f[m-1][n-1]
答案是:f[m-1][n-1]
時(shí)間復(fù)雜度:O(MN),空間復(fù)雜度(數(shù)組大小):O(MN)
3. 代碼實(shí)現(xiàn)
public int uniquePaths(int m, int n) {int[][] f = new int[m][n];f[0][0] = 1;for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (i == 0 || j == 0) {f[i][j] = 1;} else {f[i][j] = f[i][j - 1] + f[i - 1][j];}}}return f[m - 1][n - 1];}2. 帶阻礙的矩陣總路徑數(shù)
1. 題目描述
給定 m 行 n 列的網(wǎng)格,有一個(gè)機(jī)器人從左上角(0,0)出發(fā),每一步可以向下或者向右走一步。網(wǎng)格中有些地方有障礙,機(jī)器人不能通過障礙格。問有多少種不同的方式走到右下角?
2. 思路
f[i][j] = f[i][j-1] + f[i-1][j]
f[0][0] = 1
計(jì)算第0行:f[0][0], f[0][1], …, f[0][n-1]
計(jì)算第1行: f[1][0], f[1][1], …, f[1][n-1]
…
計(jì)算第m-1行: f[m-1][0], f[m-1][1], …, f[m-1][n-1]
答案是:f[m-1][n-1]
時(shí)間復(fù)雜度:O(MN),空間復(fù)雜度(數(shù)組大小):O(MN)
3. 代碼實(shí)現(xiàn)
public int uniquePathsWithObstacles(int[][] board) {int m = board.length;int n = board[0].length;if (m == 0 || n == 0) {return 0;}int[][] f = new int[m][n];for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (i == 0 || j == 0) {f[i][j] = 1;continue;}if (board[i][j] == 1) {continue;}if (i > 0) {f[i][j] += f[i - 1][j];}if (j > 0) {f[i][j] += f[i][j - 1];}}}return f[m - 1][n - 1];}3. 矩陣的最小路徑和
1. 題目描述
給定 m 行 n 列的網(wǎng)格,每個(gè)格子(i,j)里都一個(gè)非負(fù)數(shù) A[i][j]。求一個(gè)左上角(0,0)到右下角的路徑,每一步只能向下或者向右走一步,使得路徑上的格子里的數(shù)字之和最小。輸出最小數(shù)字和
2. 思路
f[i][j] = min(f[i][j-1], f[i-1][j])+board[i][j]
f[0][0] = 1
計(jì)算第0行:f[0][0], f[0][1], …, f[0][n-1]
計(jì)算第1行:f[1][0], f[1][1], …, f[1][n-1]
…
計(jì)算第m-1行:f[m-1][0], f[m-1][1], …, f[m-1][n-1]
f[i][j] =min{ f[i-1][j] + f[i][j-1]}+board[i][j]
時(shí)間復(fù)雜度:O(MN),空間復(fù)雜度O(MN)
3. 代碼實(shí)現(xiàn)
public int minPathSum(int[][] board) {int m = board.length;int n = board[0].length;if (m == 0 || n == 0) {return 0;}int[][] f = new int[m][n];for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (i == 0 && j == 0) {f[i][j] = board[0][0];continue;}int t = Integer.MAX_VALUE;if (i > 0) {t = Math.min(f[i - 1][j], t);}if (j > 0) {t = Math.min(f[i][j - 1], t);}f[i][j] = t + board[i][j];}}return f[m - 1][n - 1];}總結(jié)