如何使用两个不同的路径遍历网格以最大化路径的总和?

时间:2014-01-10 04:00:01

标签: algorithm

我有一个N×N网格,每个框都有值。我必须从左上角移动到右下角(路径1),从右上角移动到左下角(路径2)。当我从左上角移动到右下角时,我只能向下或向右移动。同样,当我从右上角移动到左下角时,我只能左右移动。

但如果我在走路1时向下移动,路径2的相应移动应该在左边。类似地,如果我在采用路径1时向右移动,则路径2的相应移动应该是向下的。

当我们采用两条路径时,我们总结了每个框中遇到的值。我们可以获得的最大值是多少?

以下面的网格为例:

 6   0   3  -1

 7   4   2   4

-3   3  -2   8

13  10  -1  -4 

我们可以采用的最佳路径表示如下:路径1由*表示,而路径2由〜表示。

(6*)  (0)   (3~)  (-1~)

(7*)  (4*~) (2~)  (4)

(-3)  (3*~) (-2*) (8*)

(13~) (10~) (-1)  (-4*)

这两条路径的总和是56.

我们必须设计一种算法来计算给定任意N×N网格的最大可能得分。

很明显这是一个DP问题。所以,我试图确定一个递归关系,可以这么说。我尝试使用从N乘M网格中找到所有路径的最大总和的经典问题的递归关系,但这不起作用,因为它太复杂了。

我试图将N乘N网格划分为四个(N-1)个重叠的网格(N-1),因此在3乘3网格中进行演示:

a1 a2 a3

a4 a5 a6

a7 a8 a9

我把它分为四个2 x 2网格:

a1 a2  ,   a2 a3   ,   a4 a5   ,  a5 a6

a4 a5  ,   a5 a6   ,   a7 a8   ,  a8 a9

假设我们知道所有这些网格的最佳路径,那么我们可以为更大的网格计算最佳路径吗?

嗯,这似乎很有希望,但我很快发现这些复发关系,取决于更大的案例。例如,

如果我们考虑第二个2 x 2网格,假设我们知道最佳路径1和路径2 = S.现在,显然,对于我们从a1到a2,我们需要向右移动,但这意味着在子案例中的第一次移动(路径2中的第一次移动)应该是向下移动,这是不能保证的。

我们如何解决这个问题?

2 个答案:

答案 0 :(得分:4)

移动这两个点的规则相当于通过网格找到单个路径,该网格是网格和自身旋转-90度(向左90度/逆时针/逆时针90度)的总和,具体取决于您的区域设置)。

左上角的“向下”对应于右上角的“左”,当旋转-90度时,它向下。左上角的“右”对应于右上角的“向下”,当旋转-90度为右时。 (知道吗?)

所以你的示例网格是

 6-1   0+4   3+8  -1-4        5   4  11  -5

 7+3   4+2   2-2   4-1       10   6   0   3
                          =
-3+0   3+4  -2+3   8+10      -3   7   1  18

13+6  10+7  -1-3  -4+13      19  17  -4   9

现在,您可以通过任何常用方法找到从左上角到右下角的路径。实际上,您不需要路径,只需要最大总和,这更容易:通过添加从左上角向下折叠矩阵。初始条件是上面的网格。下一步是将左上角的值添加到其有效的邻居:

     9  11  -5

15   6   0   3

-3   7   1  18

19  17  -4   9

然后选择具有两个有效邻居的任何网格点的两个邻居中较大的一个(这里21大于20和12):

        20  -5

    21   0   3

12   7   1  18

19  17  -4   9

等等......

            15

        21   3              24
                ->                  
    28   1  18           29 18     ->        47
                                                    ->  
31  17  -4   9        48 -4  9            44  9            56

我刚刚手动解决了你的4x4案例,答案是56.

答案 1 :(得分:1)

您可以将此减少到一个网格上只有一个路径的情况。制作网格的第二个副本,旋转第二个副本,然后将它们矩阵添加在一起,并使用一个路径在新网格上求解。动态编程问题很容易(即为每个节点计算部分最大值)。