dp[i][j]
表示:走到 [i, j]
位置的时候,一共有多少种方式[i, j]
位置之前的一小步,有两种情况 [i-1, j]
的位置向下走一步,到达 [i, j]
[i, j-1]
的位置向右走一步,到达 [i, j]
dp[i][j] = dp[i-1][j] + dp[i][j-1]
dp[m][n]
public int uniquePaths(int m, int n) {
//1. 创建 dp 表
int[][] dp = new int[m+1][n+1];
//2. 初始化
dp[0][1] = 1;
//3. 填表
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
dp[i][j] = dp[i-1][j] +dp[i][j-1];
}
}
return dp[m][n];
}
dp[i][j]
表示:到达 [i, j]
位置的时候,一共有多少种方法dp[i][j]
0
dp[i][j] = dp[i-1][j] + dp[i][j-1]
dp=0
里面的值,要保证后面的填表是正确的
0
是不产生影响的)1
,其他都为 0
就行了下标的映射关系
(0, 0)
跑到了 (1, 1)
位置,(2, 3)
跑到了 (3, 4)
位置。加入虚拟格子之后,整体向右下移动了dp
表找回之前矩阵的位置,那么下标就得统一 -1
才可以dp[m][n]
public int uniquePathsWithObstacles(int[][] ob) {
//1. 创建 dp 表
int m = ob.length;
int n = ob[0].length;
int[][] dp = new int[m+1][n+1];
//2. 初始化
dp[1][0] = 1;
//3. 填表
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if(ob[i-1][j-1] == 0) {
dp[i][j] = dp[i-1][j] +dp[i][j-1];
}
}
}
return dp[m][n];
}
dp
表在创建的时候,里面的值本来就是 0
,所以我们只需要看一下没有障碍物时候的情况 ob
二维数组的值是 0
还是 1
即可时间复杂度:
m*n
(两个for
循环) 空间复杂度:m*n
(弄了个二维dp
表)
dp[i][j]
表示:走到 [i, j]
位置时,此时的最大价值dp[i][j]
[i-1, j]
走过来==> dp[i-1][j] + g[i][j]
[i, j-1]
走过来==> dp[i][j-1] + g[i][j]
dp[i][j] = max(dp[i-1][j], dp[i][j-1]) + g[i][j]
里面的值,要保证后面的填表是正确的
下标的映射
-1
即可dp[m][n]
public int jewelleryValue(int[][] frame) {
//1. 创建 dp 表
int m = frame.length;
int n = frame[0].length;
int[][] dp = new int[m+1][n+1];
//2. 初始化
//3. 填表
for (int i = 1; i <= m; i++)
for (int j = 1; j <= n; j++)
dp[i][j] = Math.max(dp[i-1][j],dp[i][j-1]) + frame[i-1][j-1];
return dp[m][n];
}
-1
,返回到原来的位置时间复杂度:
m*n
(两个for
循环) 空间复杂度:m*n
(弄了个二维dp
表)