1. 不同路径 (LC62)
题目描述

解题思路
- 状态表示:dp[i][j]表示到(i,j)有dp[i][j]中路径
- 状态转移方程:
dp[i][j] = dp[i-1][j]+dp[i][j-1] - 初始化:
i=0或j=0没有路径,dp[1][1]=1
代码实现
java
class Solution {
public int uniquePaths(int m, int n) {
int[][] dp = new int[m+1][n+1];
dp[1][1] = 1;
for(int i = 1;i<=m;i++){
for(int j = 1;j<=n;j++){
if(i==1 && j == 1)
continue;
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
return dp[m][n];
}
}
2. 不同路径 II(LC63)
题目描述

代码实现
java
class Solution {
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
int m = obstacleGrid.length;
int n = obstacleGrid[0].length;
int[][] dp = new int[m+1][n+1];
dp[0][1] = 1;
for(int i = 1;i<=m;i++){
for(int j = 1;j<=n;j++){
if(obstacleGrid[i-1][j-1]==0)
dp[i][j] = dp[i-1][j]+dp[i][j-1];
}
}
return dp[m][n];
}
}
3. 珠宝的最高价值(LC166)
题目描述

代码实现
java
class Solution {
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 = 1;i<=m;i++){
for(int j = 1;j<=n;j++){
dp[i][j] = Math.max(frame[i-1][j-1]+dp[i-1][j],frame[i-1][j-1]+dp[i][j-1]);
}
}
return dp[m][n];
}
}
4. 下降路径最小和(LC931)
题目描述

解题思路
- 状态表示:到达(i,j)最小路径和为
dp[i][j] - 状态转移方程:
dp[i][j] = min(dp[i-1][j-1],dp[i-1][j],dp[i-1][j+1]+matrix[i-1][j-1] - 初始化:
- 要在原数组的规模上 上方加上一行,两边各加一列,
int[] dp = new int[n+1][n+2] - 两边要初始化为无穷小,上方初始化为0。
- 要在原数组的规模上 上方加上一行,两边各加一列,
代码实现
java
class Solution {
public int minFallingPathSum(int[][] matrix) {
int n = matrix.length;
int[][] dp = new int[n+1][n+2];
for(int[] arr : dp)
Arrays.fill(arr,Integer.MAX_VALUE);
for(int i = 0;i<=n+1;i++)
dp[0][i]=0;
for(int i = 1;i<=n;i++){
for(int j = 1;j<=n;j++){
dp[i][j] = Math.min(dp[i-1][j-1],Math.min(dp[i-1][j],dp[i-1][j+1]))+matrix[i-1][j-1];
}
}
int ret = Integer.MAX_VALUE;
for(int i = 0;i<=n;i++)
ret = Math.min(dp[n][i],ret);
return ret;
}
}
5. 最小路径和(LC64)
题目描述

解题思路
如果按照之前的思路,多加一行多加一列,初始化dp所有值都是0,直接用dp[i][j] = Math.min(dp[i-1][j],dp[i][j-1])+grid[i-1][j-1]计算第一行和第一列,会直接把边界的0当做最小值,而之前填过的路径和永远比边界小。这种情况下应该先初始化第1行和第1列,而多加的一行0和一列0就没用了。可以初始化为无穷大

也可以直接创建相同规模的dp,初始化第一行第一列,再填表
代码实现
java
class Solution {
public int minPathSum(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
int[][] dp = new int[m][n];
dp[0][0] = grid[0][0];
//初始化第一行和第一列
for(int i = 1;i<m;i++)
dp[i][0] = dp[i-1][0]+grid[i][0];
for(int j = 1;j<n;j++)
dp[0][j] = dp[0][j-1]+grid[0][j];
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][j];
return dp[m-1][n-1];
}
}
6. 地下城游戏(LC174)
题目描述

解题思路
- 状态表示:(i,j)为起点到终点的最低生命值为dp[i][j]
- 状态转移方程:
dp[i][j] = Math.min(dp[i+1][j],dp[i][j+1]) - dungeon[i][j];找到右边和下边的最小值减去当前的数值。如果为负数,说明不需要额外的初始值就可以走到终点,直接置为1
代码实现
java
class Solution {
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-1][n] = dp[m][n-1] = 1;
for(int i = m-1;i>=0;i--){
for(int j = n-1;j>=0;j--){
dp[i][j] = Math.min(dp[i+1][j],dp[i][j+1]) - dungeon[i][j];
dp[i][j] = Math.max(dp[i][j],1);
}
}
return dp[0][0];
}
}