给定一个维度为N * M的矩阵mat[][] ,任务是找到从左上角单元格(0, 0) 到右下角单元格(N – 1, M – 1) 的路径。矩阵,使得路径中元素的总和最大。从矩阵的任何单元格 (i, j) 允许的唯一移动是(i + 1, j)或(i, j + 1) 。
例子:
Input: mat[][] = {{3, 7}, {9, 8}}
Output: 20
Explanation:
Path with maximum sum is 3 => 9 => 8 as 20.
Input: mat[][] = {{1, 2}, {3, 5}}
Output: 9
Explanation:
Path with maximum sum is 1 => 3 => 5 as 9
方法一(自下而上):思路是用动态规划来解决这个问题。关键观察是单元格 grid[i][j]只能从grid[i – 1][j]或grid[i][j – 1]到达。因此,该问题的递推关系由以下等式给出:
sum(i, j) = max(sum(i – 1, j), sum(i, j – 1)) + grid[i][j]
- 初始化维度为N * M的辅助矩阵sum[][] 。
- 迭代矩阵元素并使用上述形成的递推关系更新辅助矩阵sum[][] 的每个单元格。
- 完成上述步骤后,将值总和[N] [M]将包含从左上角到给定矩阵的右下角的路径的最大总和可能的。打印那个总和。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the maximum sum
// path in the grid
int MaximumPath(vector >& grid)
{
// Dimensions of grid[][]
int N = grid.size();
int M = grid[0].size();
// Stores maximum sum at each cell
// sum[i][j] from cell sum[0][0]
vector > sum;
sum.resize(N + 1,
vector(M + 1));
// Iterate to compute the maximum
// sum path in the grid
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= M; j++) {
// Update the maximum path sum
sum[i][j] = max(sum[i - 1][j],
sum[i][j - 1])
+ grid[i - 1][j - 1];
}
}
// Return the maximum sum
return sum[N][M];
}
// Driver Code
int main()
{
vector > grid
= { { 1, 2 }, { 3, 5 } };
cout << MaximumPath(grid);
return 0;
}
Java
// Java program for
//the above approach
import java.util.*;
class GFG{
// Function to find the maximum sum
// path in the grid
static int MaximumPath(int [][]grid)
{
// Dimensions of grid[][]
int N = grid.length;
int M = grid[0].length;
// Stores maximum sum at each cell
// sum[i][j] from cell sum[0][0]
int [][]sum = new int[N + 1][M + 1];
// Iterate to compute the maximum
// sum path in the grid
for (int i = 1; i <= N; i++)
{
for (int j = 1; j <= M; j++)
{
// Update the maximum path sum
sum[i][j] = Math.max(sum[i - 1][j],
sum[i][j - 1]) +
grid[i - 1][j - 1];
}
}
// Return the maximum sum
return sum[N][M];
}
// Driver Code
public static void main(String[] args)
{
int [][]grid = {{1, 2}, {3, 5}};
System.out.print(MaximumPath(grid));
}
}
// This code is contributed by shikhasingrajput
Python3
# Python3 program for the above approach
# Function to find the maximum sum
# path in the grid
def MaximumPath(grid):
# Dimensions of grid[][]
N = len(grid)
M = len(grid[0])
# Stores maximum sum at each cell
# sum[i][j] from cell sum[0][0]
sum = [[0 for i in range(M + 1)]
for i in range(N + 1)]
# Iterate to compute the maximum
# sum path in the grid
for i in range(1, N + 1):
for j in range(1, M + 1):
# Update the maximum path sum
sum[i][j] = (max(sum[i - 1][j],
sum[i][j - 1]) +
grid[i - 1][j - 1])
# Return the maximum sum
return sum[N][M]
# Driver Code
if __name__ == '__main__':
grid = [ [ 1, 2 ], [ 3, 5 ] ]
print(MaximumPath(grid))
# This code is contributed by mohit kumar 29
C#
// C# program for the above approach
using System;
class GFG{
// Function to find the maximum sum
// path in the grid
static int MaximumPath(int [,]grid)
{
// Dimensions of grid[,]
int N = grid.GetLength(0);
int M = grid.GetLength(1);
// Stores maximum sum at each cell
// sum[i,j] from cell sum[0,0]
int [,]sum = new int[N + 1, M + 1];
// Iterate to compute the maximum
// sum path in the grid
for(int i = 1; i <= N; i++)
{
for(int j = 1; j <= M; j++)
{
// Update the maximum path sum
sum[i, j] = Math.Max(sum[i - 1, j],
sum[i, j - 1]) +
grid[i - 1, j - 1];
}
}
// Return the maximum sum
return sum[N, M];
}
// Driver Code
public static void Main(String[] args)
{
int [,]grid = { { 1, 2 }, { 3, 5 } };
Console.Write(MaximumPath(grid));
}
}
// This code is contributed by Amit Katiyar
Javascript
C++
#include
using namespace std;
vector > dp;
// Function to find the maximum sum path in the grid
int MaximumPathUtil(int i, int j, vector >& grid)
{
// Base condition
if (i == 0 || j == 0)
return 0;
// If current subproblem is already computed,
// we simply return its result from the dp table
if (dp[i][j] != -1)
return dp[i][j];
// Computing the current subproblem and
// store the result in the dp table for future use
return dp[i][j] = max(MaximumPathUtil(i, j-1, grid), MaximumPathUtil(i - 1, j, grid)) +
grid[i-1][j-1];
}
int MaximumPath(vector >& grid)
{
// Dimensions of grid[][]
int n = grid.size();
int m = grid[0].size();
// dp table to memoize the subproblem results
dp.resize(n+1, vector (m+1, -1));
// dp[n][m] gives the max. path sum
// from grid[0][0] to grid[n-1][m-1]
return MaximumPathUtil(n, m, grid);
}
// Driver Code
int main()
{
vector > grid = {{3, 7, 9, 2, 7},
{9, 8, 3, 5, 5},
{1, 7, 9, 8, 6},
{3, 8, 6, 4, 9},
{6, 3, 9, 7, 8}};
cout << MaximumPath(grid);
return 0;
}
// This code is contributed by tridib_samanta
9
时间复杂度: O(N * M)
辅助空间: O(N * M)
方法二(自顶向下):我们会以自顶向下的方式递归解决问题。我们根据到达单元格 grid[i][j]的两种方式制定递归如下:
- 如果我们从单元格 grid[i][j-1]向右移动一步,或者,
- 如果我们从单元格 grid[i-1][j]向下移动一步。
dp[i][j] = max(dp[i][j-1], dp[i-1][j]) + grid[i][j]
因此,我们需要选择给我们最大值的步骤(在上述两个之间)。此外,我们需要添加存在于我们步入的单元格中的值,即grid[i][j] 。由于这个问题具有重叠子问题的性质,我们可以将子问题的结果(memoize)存储在一个二维矩阵中(我们称之为dp ),以避免重复计算相同的子问题。最初,我们将dp表中的所有单元格设置为值 -1,并且每次找到子问题的答案时,我们都会在dp表中的相应单元格中覆盖其结果。因此,在计算任何子问题之前,我们曾经检查过 – 如果该特定子问题之前已解决或未解决,如果已解决(即其对应的单元格dp矩阵不是 -1)我们简单地返回该值,否则我们解决它并将结果存储在dp表中。
下面是上述方法的实现:
C++
#include
using namespace std;
vector > dp;
// Function to find the maximum sum path in the grid
int MaximumPathUtil(int i, int j, vector >& grid)
{
// Base condition
if (i == 0 || j == 0)
return 0;
// If current subproblem is already computed,
// we simply return its result from the dp table
if (dp[i][j] != -1)
return dp[i][j];
// Computing the current subproblem and
// store the result in the dp table for future use
return dp[i][j] = max(MaximumPathUtil(i, j-1, grid), MaximumPathUtil(i - 1, j, grid)) +
grid[i-1][j-1];
}
int MaximumPath(vector >& grid)
{
// Dimensions of grid[][]
int n = grid.size();
int m = grid[0].size();
// dp table to memoize the subproblem results
dp.resize(n+1, vector (m+1, -1));
// dp[n][m] gives the max. path sum
// from grid[0][0] to grid[n-1][m-1]
return MaximumPathUtil(n, m, grid);
}
// Driver Code
int main()
{
vector > grid = {{3, 7, 9, 2, 7},
{9, 8, 3, 5, 5},
{1, 7, 9, 8, 6},
{3, 8, 6, 4, 9},
{6, 3, 9, 7, 8}};
cout << MaximumPath(grid);
return 0;
}
// This code is contributed by tridib_samanta
输出:
67
时间复杂度: O(n*m)
空间复杂度: O(n*m)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。