在处理另一个问题时,我遇到了一个问题:
给出一个矩阵和一个整数 k ,找到矩阵中长度为 k 的路径,该路径将路径中单元格的总和最大化。该路径可以在任何单元开始,可以在任何方向进行,并且可以在每个点自由旋转。路径也可以相交,但如果确实相交,则给定的像元仅对总和一次进行计数。
返回总和。
为了解决这个问题,我尝试了一种递归方法,在该方法中,对于每个可能的起始位置(即矩阵的所有元素),我计算了可能的最长路径,并尝试使用查找表,以便重复某个点在网格中得出的值为0。问题是我不确定如何以及何时重新初始化查找表,以免丢失可能的路由。
到目前为止,我的实现看起来像这样。
int maxP(int i, int j, int steps, int[][] grid) {
if (i < 0 || i >= n || j < 0 || j >= m || steps < 0) {
return 0;
}
// check if place has been passed through before
int cost;
if (lookup[i][j] == 1) {
cost = 0;
} else {
cost = grid[i][j];
lookup[i][j] = 1;
}
return cost + max(
maxP(i - 1, j - 1, steps - 1, grid),
maxP(i - 1, j, steps - 1, grid),
maxP(i - 1, j + 1,steps - 1, grid),
maxP(i, j - 1, steps - 1, grid),
maxP(i, j + 1, steps - 1, grid),
maxP(i + 1, j - 1, steps - 1, grid),
maxP(i + 1, j, steps - 1, grid),
maxP(i + 1, j + 1, steps - 1, grid)
);
}
答案 0 :(得分:0)
“如何以及何时重新初始化查询表” 的答案是lookup[i][j]
必须是访问网格位置的次数的计数。输入网格位置时,增加计数。回溯时,减少计数。也就是说,您永远不会“重新初始化查找表” 。您始终以递增方式维护表。
这是修改后的代码:
int maxP(int i, int j, int steps, int[][] grid) {
if (i < 0 || i >= n || j < 0 || j >= m || steps < 0) {
return 0;
}
// check if place has been passed through before
int cost = 0;
if (lookup[i][j] == 0) {
cost = grid[i][j];
}
// mark this place as visited
lookup[i][j]++;
// find the best cost recursively
cost = cost + max(
maxP(i - 1, j - 1, steps - 1, grid),
maxP(i - 1, j, steps - 1, grid),
maxP(i - 1, j + 1,steps - 1, grid),
maxP(i, j - 1, steps - 1, grid),
maxP(i, j + 1, steps - 1, grid),
maxP(i + 1, j - 1, steps - 1, grid),
maxP(i + 1, j, steps - 1, grid),
maxP(i + 1, j + 1, steps - 1, grid)
);
// undo the change to the lookup table
lookup[i][j]--;
return cost;
}