


public int uniquePaths(int m, int n) {
int[][] dp = new int[m + 1][n + 1];
dp[0][1] = 1;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
dp[i + 1][j + 1] = dp[i][j + 1] + dp[i + 1][j];
}
}
return dp[m][n];
}与上道题不同路径十分相似, 只是添加了障碍物


public int uniquePathsWithObstacles(int[][] obstacleGrid) {
// 创建dp表
int m = obstacleGrid.length;
int n = obstacleGrid[0].length;
int[][] dp = new int[m + 1][n + 1];
// 初始化
dp[0][1] = 1;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (obstacleGrid[i][j] == 0) {
dp[i + 1][j + 1] = dp[i][j + 1] + dp[i + 1][j];
}
}
}
return dp[m][n];
}与上面的题类似, 甚至更简单


public int jewelleryValue(int[][] frame) {
int m = frame.length;
int n = frame[0].length;
int[][] dp = new int[m + 1][n + 1];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
dp[i + 1][j + 1] = Math.max(dp[i][j + 1],dp[i + 1][j]) + frame[i][j];
}
}
return dp[m][n];
}题目意思是:到达一个位置有左右上角与上方三种到达方式, 求路径上数字最小和, 这里需要注意重点不再是右下角, 而是最后一行全是终点


public int minFallingPathSum(int[][] matrix) {
// 创建dp表
int m = matrix.length;
int n = matrix[0].length;
int[][] dp = new int[m + 1][n + 2];
// 初始化dp表
for (int i = 0; i < m + 1; i++) {
dp[i][0] = dp[i][n + 1] = Integer.MAX_VALUE;
}
// 求dp值
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n ; j++) {
dp[i][j] = Math.min(dp[i - 1][j], Math.min(dp[i - 1][j - 1], dp[i - 1][j + 1])) + matrix[i - 1][j - 1];
}
}
int ret = dp[m][1];
for (int j = 2; j <= n; j++) {
ret = Math.min(ret, dp[m][j]);
}
return ret;
}
与上面的题基本类似, 大差不差, 这里直接上图

public int minPathSum(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
int[][] dp = new int[m + 1][n + 1];
for (int i = 0; i <= m; i++) {
dp[i][0] = Integer.MAX_VALUE;
}
for (int j = 0; j <= n; j++) {
dp[0][j] = Integer.MAX_VALUE;
}
dp[0][1] = dp[1][0] = 0;
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i - 1][j - 1];
}
}
return dp[m][n];
}这道题是很经典的使用以某位置为起点的题型, 题目两个重点是:①进入第一个钢筋和出最后一个房间都要计算其中的点数 ②健康值必须大于0


public int calculateMinimumHP(int[][] dungeon) {
int m = dungeon.length;
int n = dungeon[0].length;
int[][] dp = new int[m + 1][n + 1];
for (int i = 0; i <= m; i++) {
dp[i][n] = Integer.MAX_VALUE;
}
for (int j = 0; j <= n; j++) {
dp[m][j] = Integer.MAX_VALUE;
}
dp[m][n - 1] = dp[m - 1][n] = 1;
for (int i = m - 1; i >= 0; i--) {
for (int j = n - 1; j >= 0; j--) {
dp[i][j] = Math.max(1, (Math.min(dp[i][j + 1], dp[i + 1][j]) - dungeon[i][j]));
}
}
return dp[0][0];
}