找到路径交叉矩阵,最大值前向然后向后

时间:2015-09-17 12:38:44

标签: algorithm

如果我有一个矩阵,矩阵的每个元素都是一个非负数。我想从左下角到右上角穿过矩阵。在每一步中,我只能向上或向右移动,每个被访问的元素将被设置为0;之后,我从右上角走到左下角,每一步我都只能向下或向左移动。

我的问题是如何有效地找到最大总和的路径。

1 个答案:

答案 0 :(得分:4)

我们有一个包含N行和M列的矩阵,并假设N>=2M>=2,否则解决方案是微不足道的。我使用动态编程在O(max(M,N) * min(N,M)^4)中运行算法。

首先,让我们证明路径不交叉的最佳解决方案(开始和结束时除外)始终存在。我们将采用任何解决方案,并在不降低优化功能的情况下转换为非交叉解决方案。

<强>证明:

首先确保第二条路径(从右上角到左下角)始终位于第一条路径的上方或同一条线上。通过将这两个路径的单个部分放在不合适的位置并交换它们来做到这一点。插图:

path swapping

然后,一次删除一次碰撞。您始终可以找到碰撞,使至少有一条路线转向那里,您可以更改该路径以避免碰撞。重复此操作,直到删除所有碰撞。一步说明:

removing collison

我们看到,不仅没有从两个路径中删除的元素组合在一起,而且添加了更多元素,并且所有元素都是非负的,因此总和只能增加。

算法:

我们只会考虑不交叉的路径,我也会假设N<=M(矩阵宽度至少为高度)。我们通常会在一列中添加数字,可以使用Prefix sum快速完成。

我们将从第一列开始。对于每对(i,j),1<=i<j<=N我们将计算该对的得分,即两条路径从(1,1)开始覆盖多少的总和分别以(1,i)和(1,j)结束。例如:

Matrix:
1 2 3
4 5 6
7 8 9

score(1,1) = 7
score(1,3) = 12
score(2,3) = -inf (paths cannot cross)

然后我们将根据当前列中的对的得分计算下一列中每对的得分。对于下一列中的每一对,只需查看上一列中可以扩展其路径以匹配当前列路径的所有对。

最后,您的答案是最后一列中对(N-1, N)的得分。我为在解释书面媒体的算法上表示糟糕而道歉,我希望这不是完全不可理解的。