给定一个维度为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[][] 的二维矩阵中,以便在每个有效索引处我们得到从该索引开始的整行的总和。
b[i][j] = arr[i][j] + b[i][j + 1]
- 现在我们检查每一个连续的两行并找到它们对应列的总和,同时更新最大总和变量。到目前为止,我们已经从上述结构中找到了两条水平线。
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
时间复杂度:
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。
- 首先,我们计算每一行的后缀总和,并将其存储在另一个称为b[][] 的二维矩阵中,以便在每个有效索引处我们得到从该索引开始的整行的总和。