📌  相关文章
📜  当恰好允许两次向左移动时,在 2D 矩阵中查找最大路径和

📅  最后修改于: 2021-09-17 06:55:47             🧑  作者: Mango

给定一个维度为N * M的二维矩阵arr[][] ,其中N是行数, M是列数。任务是在这个矩阵中找到满足某些条件的最大路径和,如下所示:

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

    示例
    显示路径的二维矩阵

    例子:

    输入: 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[][] 的二维矩阵中,以便在每个有效索引处我们得到从该索引开始的整行的总和。
    2. 现在我们检查每一个连续的两行并找到它们对应列的总和,同时更新最大总和变量。到目前为止,我们已经从上述结构中找到了两条水平线。

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

    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)

    如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程