【问题标题】:The best route traversing a maze穿越迷宫的最佳路线
【发布时间】:2016-08-30 22:39:31
【问题描述】:

给定一个维度为(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)。一旦有人访问了该单元格,该单元格的值将设置为零。鉴于此约束,这两条路径的最大总和是多少?

感谢任何提示。谢谢。

【问题讨论】:

  • 原问题的哪一部分说一个单元格在被遍历时变为零?
  • 而你只有两个选择,右和下。如果右边的单元格变为零,那么其他人的唯一选择就是向下。他们是轮流交替,还是一个人先完成迷宫?
  • @cricket_007:我也觉得这很令人困惑,但我相信部分问题在第二段中给出。
  • 为问题添加另一条路径会将其从贪婪修改为 DP。因此,该方法应该完全不同:对于任何可能的路径 - 计算可以添加的最大路径,将任何交叉单元格视为第二条路径的“零”。然后迭代结果并选择最大值。
  • @alfasin:这两条路径的最大总和是否必然由两条不相互交叉的路径组成?

标签: algorithm dynamic-programming


【解决方案1】:

首先请注意,每一步总是将曼哈顿距原点 (x + y) 的距离增加一。这意味着,如果您一次将两个标记沿着两条路径移动,并交替移动,那么如果路径穿过计数器,则最终必须彼此重叠:您不能让一个标记到达一个正方形,而另一个标记在几个移动前腾出.

现在您可以将原始 MaxPathSum(i,j)=... 计算视为状态空间上的动态程序,其中状态是单个标记的位置。对于两条路径,一件显而易见的事情是在状态空间中运行一个动态程序,其中状态是两个标记的位置。然后你可以有 MaxPathSum(i,j,k,l)=... 其中一个更复杂的表达式考虑两个标记的四个可能的移动,并确保 Matrix[i,j] 如果 i==j && 不计算两次k==l。由于我们在上面的工作,我们只需要考虑这种形式的碰撞,所以我们不必记住标记到它们当前位置的路径。

这看起来像是状态空间大小的平方。这很糟糕,但也没有那么糟糕,这又是因为曼哈顿距离的限制。您可以通过一系列步骤进行递归计算,每一步都计算出与原点之间特定曼哈顿距离的状态的所有答案。您只需要考虑彼此具有相同曼哈顿差异的州对。如果您有一个 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 次方。

【讨论】:

    【解决方案2】:

    如果值为非负数 (>=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
    

    非最佳部分是在第一个路径元素上设置的零。这些零力 第二条不跨越第一条的路径。改进操作使用交叉点周围的元素,因此改进会在结果中添加一些相邻元素。它可用于将第一个路径元素设置为某个邻居值的值。现在,我不确定要使用哪个邻居,因为有更多的组合,特别是如果交叉是更长的重叠。我认为好的起点是将其设置为尽可能小的邻居值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-24
      • 1970-01-01
      • 2020-06-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多