考虑以下问题:
给定无符号整数的二维数组和最大长度 n ,在该矩阵中找到一个不长于 n 的路径最大化总和。输出应包括路径和总和。
路径由相邻整数组成,这些整数可以位于同一行,也可以位于同一列中,也可以沿着右下方向的对角线。
例如,请考虑以下矩阵和3
的给定路径长度限制:
1 2 3 4 5
2 1 2 2 1
3 4 5* 6 5
3 3 5 10* 5
1 2 5 7 15*
最佳路径为5 + 10 + 15
(节点标有*
)。
现在,一旦看到这个问题,立即动态编程解决方案似乎最合适,因为这个问题与Min Cost Path或Maximum Sum Rectangular Submatrix等其他问题相似。问题是,为了正确解决这个问题,你需要从矩阵中的每个整数(节点)开始构建路径,而不是从左上角开始路径,在右下角结束。
我最初想的是一种类似于Maximum Sum Rectangular Submatrix解决方案的方法,我可以在其中存储每个节点的每条可能路径(路径长度小于 n ,只进行正确/向下),但是我可以设想这种方法的唯一方法是从每个节点进行向下和向右的递归调用,这似乎会破坏DP的目的。此外,我需要能够存储最大路径。
我想到的另一个可能的解决方案是以某种方式调整最长路径搜索并从图中的每个int运行它,其中每个int都像边缘权重。
找到最大路径的最有效方法是什么?
答案 0 :(得分:0)
使用F [i] [j] [k]作为路径长度为k并在位置(i,j)结束的最大路径和。
F [i] [j] [k]可以从F [i-1] [j] [k-1]和F [i] [j-1] [k-1]计算。
答案是F的最大值。
要检索最大路径,请使用另一个表G [i] [j] [k]来存储F [i] [j] [k]的最后一步,即它来自(i-1,j)或(i,j-1)。
答案 1 :(得分:0)
约束条件是只能通过在矩阵中向下或向右创建路径。
解决方案复杂度 O(N * M * L)其中:
L:路径的最大长度
int solve(int x, int y, int l) {
if(x > N || y > M) { return -INF; }
if(l == 1) {matrix[x][y];}
if(dp[x][y][l] != -INF) {return dp[x][y][l];} // if cached before, return the answer
int option1 = solve(x+1, y, l-1); // take a step down
int option2 = solve(x, y+1, l-1); // take a step right
maxPath [x][n][l] = (option1 > option2 ) ? DOWN : RIGHT; // to trace the path
return dp[x][y][l] = max(option1, option2) + matrix[x][y];
}
示例:solve(3,3,3):从(3,3)开始的最大路径总和,长度为3(2步)