【发布时间】:2021-06-18 01:44:51
【问题描述】:
我现在正在为我的 comp 课做作业,目前正在掌握动态编程的窍门。我们当前的任务是给定一个大小为m x n 的矩阵,其中 m 或 n 保证至少为 2。这个矩阵充满了各种值,这些值指示我们可以从所述位置移动多少“步”任何基本方向,目标是我们从索引 (0,0) 开始,并且必须前往索引 (n-1,m-1),或者更好地说,是矩阵的右下角,在尽可能少的行程。如果这样的路径是不可能的,我们必须返回 -1。这是一个例子:
| 1 | 2 |
|---|---|
| 7 | 5 |
| 6 | 3 |
从左上角到右下角所需的最小跳跃量是 2,因为我们从 (0,0) 开始,它的值为 1,意味着我们可以向任何方向移动 1 步。然后我们转到 (0,1),它的值为 2,我们将使用它来“步进”两个位置,进入右下角的 (2,1)。总的来说,这次旅程经历了两次:一次从 (0,0) 到 (0,1),然后另一次从 (0,1) 到 (2,1)。在 (0,0) 位置,我也可以下降到 (0,1),这毫无价值,但这不会产生任何有用的结果。
我正在采用动态编程方法,使用一个表格来存储先前计算的值并缩短运行时间,并使用一个单独的表格让我知道我是否计算了该位置。我的代码如下:
private static int [][] dpArray;
private static int [][] solveState;
private static int rowDest;
private static int colDest;
public static int min_moves(int[][] board) {
rowDest = board.length - 1;
colDest = board[0].length - 1;
solveState = new int[rowDest + 1][colDest + 1];
dpArray = new int[rowDest + 1][colDest + 1];
int ans = minMoveRecur(0,0, board);
if (ans == 100000000) {
return -1;
}
private static int minMoveRecur(int row, int col, int[][] board) {
if ((row == rowDest) && (col == colDest)) {
return 0;
}
if ((row < 0) || ( rowDest < row) || (col < 0) || (colDest < col)) {
return 100000000;
}
if (solveState[row][col] == 1) {
return dpArray[row][col];
}
solveState[row][col] = 1;
int up = row - board[row][col];
int down = row + board[row][col];
int right = col + board[row][col];
int left = col - board[row][col];
int vertBest = Math.min(minMoveRecur(up,col,board),minMoveRecur(down,col,board));
int horizBest = Math.min(minMoveRecur(row,right,board),minMoveRecur(row,left,board));
dpArray[row][col] = 1 + Math.min(vertBest,horizBest);
return dpArray[row][col];
}
我有一个递归关系,可以找到导致最少跳转次数的路径,但是对于我拥有的一个测试板,我得到了错误的答案,在哪里
int [][]board = {{2},{4},{2},{0},{4},{4},{3},{5},{1},{3}};
应该跳 4 次 { (0,0) -> (2,0) -> (4,0) -> (8,0) -> (9,0) },但我一直跳到 2跳跃。我调试了几次,似乎问题与vertBest 和horizBest 没有从递归调用中获取正确的值有关。似乎vertBest 的值始终为 0,直到它为 1 的末尾,然后从初始递归调用的dpArray[row][col] = 1 + Math.min(vertBest,horizBest); 将其添加到 1 为 2。它似乎没有添加在其早期通话中的 +1 上。
谁能帮忙解释一下这里出了什么问题?
【问题讨论】:
-
这并不能回答您的问题,但您是否考虑过Dijkstra's shortest path algorithm 的修改版本?实现起来并不难(在我看来,比调试这个自定义算法更容易)并且值得为您未来的课程学习。
标签: java recursion matrix dynamic-programming