📜  当正好允许两个左移时,在2D矩阵中找到最大路径总和

📅  最后修改于: 2021-04-23 06:05:43             🧑  作者: Mango

给定尺寸为N * M的二维矩阵arr [] [] ,其中N为行数, M为列数。任务是在满足以下条件的该矩阵中找到最大路径和:

  1. 我们只能从arr [i] [M]开始,其中0 <= i <=N。
  2. 我们在同一侧结束路径,这样我们就可以精确地向左转2个弯。

    范例
    2D矩阵显示路径

    例子:

    输入: N = 3,M = 3 arr [] [] = {{1,2,3},{3,3,1},{4,1,6}}输出: 20说明如果我们遵循这条路径,则得到的总和为20。输入: N = 3,M = 3 arr [] [] = {{3,7,4},{1,9,6},{1,7,7 }}输出: 34说明如果我们沿着这条路走,那么总和为34。

    这个想法是使用动态规划并在矩阵中选择一个最佳结构,即
    C形结构,如下图所示。

    步骤如下

    1. 首先,我们计算每行的后缀总和,并将其存储在另一个称为b [] []的2D矩阵中,以便在每个有效索引处,我们从该索引开始获得整个行的总和。
    2. 现在,我们检查每两个连续的行,找到它们对应列的总和,同时更新最大sum变量。到目前为止,我们已经从上面的结构中找到了两条水平线。

      我们需要找到连接这些水平线(即列)的垂直线。

    3. 遍历每一行后,对于每个有效索引,我们有两个选择,要么将该索引链接到上一行的相应索引,即在上一列中添加,要么开始一个新列。
      无论哪个最大值,我们都会保留该值,并在此索引处更新该值。

    下面是上述方法的实现:

    C++
    // C++ program to find maximum path sum
    // in a 2D matrix when exactly two
    // left moves are allowed
    #include 
    #define N 3
    #define M 3
    using namespace std;
      
    // Function to return the maximum path sum
    int findMaxSum(int arr[][M])
    {
        int sum = 0;
        int b[N][M];
          
        // Copy last column i.e. starting and 
        // ending columns in another array
        for (int i = 0; i < N; i++) {
            b[i][M - 1] = arr[i][M - 1];
        }
          
        // Calculate suffix sum in each row
        for (int i = 0; i < N; i++) {
            for (int j = M - 2; j >= 0; j--) {
                b[i][j] = arr[i][j] + b[i][j + 1];
            }
        }
          
        // Select the path we are going to follow
        for (int i = 1; i < N; i++) {
            for (int j = 0; j < M; j++) {
                sum = max(sum, b[i][j] + b[i - 1][j]);
                  
                b[i][j] = max(b[i][j], b[i - 1][j] + arr[i][j]);
            }
        }
          
        return sum;
    }
      
    // Driver Code
    int main()
    {
        int arr[N][M] = {{ 3, 7, 4 }, 
                         { 1, 9, 6 }, 
                         { 1, 7, 7 }};
                           
        cout << findMaxSum(arr) << endl;
      
        return 0;
    }


    Java
    // Java program to find maximum path sum
    // in a 2D matrix when exactly two
    // left moves are allowed
    import java.io.*;
      
    class GFG 
    {
          
    static int N = 3;
    static int M = 3;
      
    // Function to return the maximum path sum
    static int findMaxSum(int arr[][])
    {
        int sum = 0;
        int [][]b = new int [N][M];
          
        // Copy last column i.e. starting and 
        // ending columns in another array
        for (int i = 0; i < N; i++) 
        {
            b[i][M - 1] = arr[i][M - 1];
        }
          
        // Calculate suffix sum in each row
        for (int i = 0; i < N; i++) 
        {
            for (int j = M - 2; j >= 0; j--) 
            {
                b[i][j] = arr[i][j] + b[i][j + 1];
            }
        }
          
        // Select the path we are going to follow
        for (int i = 1; i < N; i++) 
        {
            for (int j = 0; j < M; j++) 
            {
                sum = Math.max(sum, b[i][j] + b[i - 1][j]);
                  
                b[i][j] = Math.max(b[i][j], b[i - 1][j] + arr[i][j]);
            }
        }
          
        return sum;
    }
      
    // Driver Code
    public static void main (String[] args) 
    {
      
        int arr[][] = {{ 3, 7, 4 }, 
                        { 1, 9, 6 }, 
                        { 1, 7, 7 }};
                      
        System.out.println (findMaxSum(arr));
    }
    }
      
    // This code is contributed by ajit.


    Python3
    # Python3 program to find maximum path sum 
    # in a 2D matrix when exactly two 
    # left moves are allowed 
    import numpy as np
    N = 3
    M = 3
      
    # Function to return the maximum path sum 
    def findMaxSum(arr) : 
      
        sum = 0; 
        b = np.zeros((N, M)); 
          
        # Copy last column i.e. starting and 
        # ending columns in another array 
        for i in range(N) : 
            b[i][M - 1] = arr[i][M - 1]; 
          
        # Calculate suffix sum in each row 
        for i in range(N) :
            for j in range(M - 2, -1, -1) : 
                b[i][j] = arr[i][j] + b[i][j + 1]; 
          
        # Select the path we are going to follow 
        for i in range(1, N) :
            for j in range(M) :
                sum = max(sum, b[i][j] + b[i - 1][j]); 
                  
                b[i][j] = max(b[i][j], 
                              b[i - 1][j] + arr[i][j]);
                  
        return sum; 
      
    # Driver Code 
    if __name__ == "__main__" : 
      
        arr = [[ 3, 7, 4 ], 
               [ 1, 9, 6 ], 
               [ 1, 7, 7 ]]; 
                          
        print(findMaxSum(arr)); 
      
    # This code is contributed by AnkitRai01


    C#
    // C# program to find maximum path sum
    // in a 2D matrix when exactly two
    // left moves are allowed
    using System;
          
    class GFG 
    {
          
    static int N = 3;
    static int M = 3;
      
    // Function to return the maximum path sum
    static int findMaxSum(int [,]arr)
    {
        int sum = 0;
        int [,]b = new int [N, M];
          
        // Copy last column i.e. starting and 
        // ending columns in another array
        for (int i = 0; i < N; i++) 
        {
            b[i, M - 1] = arr[i, M - 1];
        }
          
        // Calculate suffix sum in each row
        for (int i = 0; i < N; i++) 
        {
            for (int j = M - 2; j >= 0; j--) 
            {
                b[i, j] = arr[i, j] + b[i, j + 1];
            }
        }
          
        // Select the path we are going to follow
        for (int i = 1; i < N; i++) 
        {
            for (int j = 0; j < M; j++) 
            {
                sum = Math.Max(sum, b[i, j] + b[i - 1, j]);
                  
                b[i, j] = Math.Max(b[i, j], b[i - 1, j] + arr[i, j]);
            }
        }
          
        return sum;
    }
      
    // Driver Code
    public static void Main () 
    {
      
        int [,]arr = {{ 3, 7, 4 }, 
                        { 1, 9, 6 }, 
                        { 1, 7, 7 }};
                      
        Console.WriteLine(findMaxSum(arr));
    }
    }
      
    /* This code contributed by PrinciRaj1992 */


    输出:
    34
    

    时间复杂度: O(N * M)