给定尺寸为N * M的二维矩阵arr [] [] ,其中N为行数, M为列数。任务是在满足以下条件的该矩阵中找到最大路径和:
- 我们只能从arr [i] [M]开始,其中0 <= i <=N。
- 我们在同一侧结束路径,这样我们就可以精确地向左转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形结构,如下图所示。步骤如下:
- 首先,我们计算每行的后缀总和,并将其存储在另一个称为b [] []的2D矩阵中,以便在每个有效索引处,我们从该索引开始获得整个行的总和。
b[i][j] = arr[i][j] + b[i][j + 1]
- 现在,我们检查每两个连续的行,找到它们对应列的总和,同时更新最大sum变量。到目前为止,我们已经从上面的结构中找到了两条水平线。
sum = max(sum, b[i][j] + b[i – 1][j])
我们需要找到连接这些水平线(即列)的垂直线。
- 遍历每一行后,对于每个有效索引,我们有两个选择,要么将该索引链接到上一行的相应索引,即在上一列中添加,要么开始一个新列。
无论哪个最大值,我们都会保留该值,并在此索引处更新该值。b[i][j] = max(b[i][j], b[i – 1][j] + arr[i][j])
下面是上述方法的实现:
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
时间复杂度:
- 首先,我们计算每行的后缀总和,并将其存储在另一个称为b [] []的2D矩阵中,以便在每个有效索引处,我们从该索引开始获得整个行的总和。