我试图了解如何使用动态编程解决在网格中查找所有唯一路径的问题:
机器人位于m x n网格的左上角(在下图中标记为“开始”)。机器人只能在任何时间点向下或向右移动。机器人正试图到达网格的右下角(在下图中标记为“完成”)。有多少可能的独特路径?
我正在查看this article,我想知道为什么在下面的解决方案中,矩阵在M_MAX + 2
和N_MAX + 2
初始化,也为什么在backtrack
的函数签名,为什么最后一个参数是使用int mat[][N_MAX+2]
const int M_MAX = 100;
const int N_MAX = 100;
int backtrack(int r, int c, int m, int n, int mat[][N_MAX+2]) {
if (r == m && c == n)
return 1;
if (r > m || c > n)
return 0;
if (mat[r+1][c] == -1)
mat[r+1][c] = backtrack(r+1, c, m, n, mat);
if (mat[r][c+1] == -1)
mat[r][c+1] = backtrack(r, c+1, m, n, mat);
return mat[r+1][c] + mat[r][c+1];
}
int bt(int m, int n) {
int mat[M_MAX+2][N_MAX+2];
for (int i = 0; i < M_MAX+2; i++) {
for (int j = 0; j < N_MAX+2; j++) {
mat[i][j] = -1;
}
}
return backtrack(1, 1, m, n, mat);
}
然后在作者的自下而上方法解决方案中:
const int M_MAX = 100;
const int N_MAX = 100;
int dp(int m, int n) {
int mat[M_MAX+2][N_MAX+2] = {0};
mat[m][n+1] = 1;
for (int r = m; r >= 1; r--)
for (int c = n; c >= 1; c--)
mat[r][c] = mat[r+1][c] + mat[r][c+1];
return mat[1][1];
}
我不知道行mat[m][n+1] = 1;
的用途是什么。
我不熟悉Java,所以如果这些归结为语法或语言特定的问题,我会道歉。
答案 0 :(得分:0)
首先,请注意作者和第二个解决方案都使用基于1的索引。所以,当然,mat[M_MAX+1][N_MAX+1]
是合理的。
现在,请注意作者正在使用的逻辑。
mat[r][c] = mat[r+1][c] + mat[r][c+1];
因此,要防止r+1
或c+1
在c = n+1
或r = m+1
时超出范围,而不是像这样添加if语句:
if (r == m)
mat[r][c] = mat[r][c+1];
if (c == n)
mat[r][c] = mat[r+1][c];
他决定只添加一个额外的行或列,其中存储有0值。因此:
mat[M_MAX+2][N_MAX+2] = {0};
最后,在自下而上的方法中,必须将mat[m][n]
初始化为1.而不是这样做,知道mat[m][n] = mat[m+1][n] + mat[m][n+1];
,他初始化了:
mat[m][n+1] = 1; // mat[m+1][n] = 0;
随意在评论中提出任何问题。