给出维度为(m,n)
的二维整数矩阵,允许一个人从(0,0)
遍历到(m-1,n-1)
。有效的举动正确或正在下降。我被要求找到到达目的地的最大总和路径。这很简单,因为
MaxPathSum(i,j) = Math.max(MaxPathSum(i,j-1),MaxPathSum(i-1,j)) + Matrix[i][j]
但是,如果有两个人都可以从(0,0)
遍历到(m-1,n-1)
。一旦某个单元格被某人访问,该单元格的值将设置为零。鉴于这种约束,这两条路径的最大总和是什么?
任何提示都表示赞赏。感谢。
答案 0 :(得分:4)
首先请注意,每一步总是将曼哈顿距离原点(x + y)的距离增加一。这意味着如果你将两个标记一次向下移动两个路径,交替移动每个标记,那么如果路径穿过计数器必须最终相互叠加:你不能有一个标记到达一个正方形而另一个空出几个在此之前。
现在,您可以将原始MaxPathSum(i,j)= ...计算视为状态空间上的动态程序,其中状态是单个标记的位置。对于两条路径,一个显而易见的事情是在状态空间上运行动态程序,其中状态是两个标记的位置。然后你可以有MaxPathSum(i,j,k,l)= ...其中一个更复杂的表达式考虑两个标记的四个可能的移动,并确保如果i == j&amp,Matrix [i,j]不计算两次;&安培;满足K ==升。由于我们上面已经解决了这个问题,我们只需要考虑这种形式的碰撞,因此我们不必记住标记对其当前位置的路径。
这看起来像是正方形的状态空间大小。这很糟糕,但并不是那么糟糕,因为曼哈顿的距离限制。您可以通过一系列步骤进行递归计算,每个步骤计算出与原点相距特定曼哈顿距离状态的所有答案。您只需要考虑彼此具有相同曼哈顿差异的状态对。如果您有NxN阵列,则原始计算成本为O(N ^ 2)。如果你想按照每个步骤覆盖具有特定曼哈顿距离的所有单元格的步骤进行,那么你有O(N)个步骤,每个步骤覆盖O(N)个单元格。如果你担心两条路径,那么你仍然有O(N)步,但每一步都覆盖O(N ^ 2)对单元,所以总成本是O(N ^ 3) - 但是输入数据(矩阵)大小为O(N ^ 2),因此您可以将其视为O(N ^ 1.5)或将原始成本提高到1.5。
答案 1 :(得分:0)
如果值为非负(> = 0),则存在一对不相互交叉的最大路径。它可以通过施工来检查。
假设最大路径(A和B)彼此交叉,如:
..B.
.B.A
AXA.
.B..
我们可以交换部分路径只是为了相互接触,其中总和是相同的。
..A.
.A.B
AXB.
.B..
由于值是非负的,因此新路径的总和> =原始A + B的总和
..A. ..A.
AA.B or .A.B
ABB. AAB.
.B.. .BB.
在我看来,某些DP解决方案应该存在,但我找不到一个: - )
有一种贪婪的方法可以找到很好的解决方案。它使用的属性 上部操作可以改善两个独立的路径。算法就像:
find first maximal path
set 0 to path elements
find second maximal path
improve paths with upper operations
非最佳部分是在第一个路径元素上设置的零。这些零力 没有越过第一条路径的第二条路径。改进操作使用交叉周围的元素,因此改进将为结果添加一些相邻元素。它可用于将第一个路径元素设置为某个邻居值的值。现在,我不确定使用哪个邻居,因为有更多的组合,特别是如果交叉是更长的重叠。我认为好的起点是将其设置为最小可能的邻居值。