给定一个n*m矩阵,任务是找到从单元格 (0, 0) 到单元格 (n-1, m-1) 的单元格元素的最大总和。
但是,允许的移动是向右、向下或对角线向右,即,从位置 (i, j) 开始,下一步可以是(i+1, j) ,或(i, j+1) ,或(i+1, j+1) 。找到满足允许移动的元素的最大总和。
例子:
Input:
mat[][] = {{100, -350, -200},
{-100, -300, 700}}
Output: 500
Explanation:
Path followed is 100 -> -300 -> 700
Input:
mat[][] = {{500, 100, 230},
{1000, 300, 100},
{200, 1000, 200}}
Output: 3000
Explanation:
Path followed is 500 -> 1000 -> 300 -> 1000 -> 200
方法:采用动态规划递归地解决上述问题。
- 在 (0, 0) 处分配矩阵开头的位置。
- 从当前位置检查每个下一个允许的位置,并选择总和最大的路径。
- 注意矩阵的边界,即,如果位置到达最后一行或最后一列,则唯一可能的选择将分别是向右或向下。
- 使用地图存储所有访问位置的轨迹,在访问任何(i,j)之前,检查该位置之前是否被访问过。
- 更新每次递归调用返回的所有可能路径的最大值。
- 直到位置到达目标单元格,即 (n-1.m-1)。
下面是上述方法的实现:
C++
#include
using namespace std;
#define N 100
// No of rows and columns
int n, m;
// Declaring the matrix of maximum
// 100 rows and 100 columns
int a[N][N];
// Variable visited is used to keep
// track of all the visited positions
// Variable dp is used to store
// maximum sum till current position
vector > dp(N, vector(N)),
visited(N, vector(N));
// For storing current sum
int current_sum = 0;
// For continuous update of
// maximum sum required
int total_sum = 0;
// Function to Input the matrix of size n*m
void inputMatrix()
{
n = 3;
m = 3;
a[0][0] = 500;
a[0][1] = 100;
a[0][2] = 230;
a[1][0] = 1000;
a[1][1] = 300;
a[1][2] = 100;
a[2][0] = 200;
a[2][1] = 1000;
a[2][2] = 200;
}
// Function to calculate maximum sum of path
int maximum_sum_path(int i, int j)
{
// Checking boundary condition
if (i == n - 1 && j == m - 1)
return a[i][j];
// Checking whether or not (i, j) is visited
if (visited[i][j])
return dp[i][j];
// Marking (i, j) is visited
visited[i][j] = 1;
// Updating the maximum sum till
// the current position in the dp
int& total_sum = dp[i][j];
// Checking whether the position hasn't
// visited the last row or the last column.
// Making recursive call for all the possible
// moves from the current cell and then adding the
// maximum returned by the calls and updating it.
if (i < n - 1 & j < m - 1) {
int current_sum = max(maximum_sum_path(i, j + 1),
max(
maximum_sum_path(i + 1, j + 1),
maximum_sum_path(i + 1, j)));
total_sum = a[i][j] + current_sum;
}
// Checking whether
// position has reached last row
else if (i == n - 1)
total_sum = a[i][j]
+ maximum_sum_path(i, j + 1);
// If the position is in the last column
else
total_sum = a[i][j]
+ maximum_sum_path(i + 1, j);
// Returning the updated maximum value
return dp[i][j] = total_sum;
}
// Driver Code
int main()
{
inputMatrix();
// Calling the implemented function
int maximum_sum = maximum_sum_path(0, 0);
cout << maximum_sum;
return 0;
}
Java
class GFG{
static final int N = 100;
// No of rows and columns
static int n, m;
// Declaring the matrix of maximum
// 100 rows and 100 columns
static int a[][] = new int[N][N];
// Variable visited is used to keep
// track of all the visited positions
// Variable dp is used to store
// maximum sum till current position
static int dp[][] = new int[N][N];
static int visited[][] = new int[N][N];
// For storing current sum
static int current_sum = 0;
// For continuous update of
// maximum sum required
static int total_sum = 0;
// Function to Input the matrix
// of size n*m
static void inputMatrix()
{
n = 3;
m = 3;
a[0][0] = 500;
a[0][1] = 100;
a[0][2] = 230;
a[1][0] = 1000;
a[1][1] = 300;
a[1][2] = 100;
a[2][0] = 200;
a[2][1] = 1000;
a[2][2] = 200;
}
// Function to calculate maximum sum of path
static int maximum_sum_path(int i, int j)
{
// Checking boundary condition
if (i == n - 1 && j == m - 1)
return a[i][j];
// Checking whether or not
// (i, j) is visited
if (visited[i][j] != 0)
return dp[i][j];
// Marking (i, j) is visited
visited[i][j] = 1;
int total_sum = 0;
// Checking whether the position hasn't
// visited the last row or the last column.
// Making recursive call for all the possible
// moves from the current cell and then adding the
// maximum returned by the calls and updating it.
if (i < n - 1 & j < m - 1)
{
int current_sum = Math.max(
maximum_sum_path(i, j + 1),
Math.max(
maximum_sum_path(i + 1, j + 1),
maximum_sum_path(i + 1, j)));
total_sum = a[i][j] + current_sum;
}
// Checking whether position
// has reached last row
else if (i == n - 1)
total_sum = a[i][j] +
maximum_sum_path(i, j + 1);
// If the position is in the last column
else
total_sum = a[i][j] +
maximum_sum_path(i + 1, j);
// Updating the maximum sum till
// the current position in the dp
dp[i][j] = total_sum;
// Returning the updated maximum value
return total_sum;
}
// Driver Code
public static void main(String[] args)
{
inputMatrix();
// Calling the implemented function
int maximum_sum = maximum_sum_path(0, 0);
System.out.println(maximum_sum);
}
}
// This code is contributed by jrishabh99
C#
// C# program to implement
// the above approach
using System;
class GFG{
static readonly int N = 100;
// No of rows and columns
static int n, m;
// Declaring the matrix of maximum
// 100 rows and 100 columns
static int[,]a = new int[N, N];
// Variable visited is used to keep
// track of all the visited positions
// Variable dp is used to store
// maximum sum till current position
static int [,]dp = new int[N, N];
static int [,]visited = new int[N, N];
// For storing current sum
static int current_sum = 0;
// For continuous update of
// maximum sum required
static int total_sum = 0;
// Function to Input the matrix
// of size n*m
static void inputMatrix()
{
n = 3;
m = 3;
a[0, 0] = 500;
a[0, 1] = 100;
a[0, 2] = 230;
a[1, 0] = 1000;
a[1, 1] = 300;
a[1, 2] = 100;
a[2, 0] = 200;
a[2, 1] = 1000;
a[2, 2] = 200;
}
// Function to calculate maximum
// sum of path
static int maximum_sum_path(int i,
int j)
{
// Checking boundary condition
if (i == n - 1 && j == m - 1)
return a[i, j];
// Checking whether or not
// (i, j) is visited
if (visited[i, j] != 0)
return dp[i, j];
// Marking (i, j) is visited
visited[i, j] = 1;
int total_sum = 0;
// Checking whether the position
// hasn't visited the last row
// or the last column.
// Making recursive call for all
// the possible moves from the
// current cell and then adding the
// maximum returned by the calls
// and updating it.
if (i < n - 1 & j < m - 1)
{
int current_sum = Math.Max(maximum_sum_path(i, j + 1),
Math.Max(maximum_sum_path(i + 1,
j + 1),
maximum_sum_path(i + 1, j)));
total_sum = a[i, j] + current_sum;
}
// Checking whether position
// has reached last row
else if (i == n - 1)
total_sum = a[i, j] +
maximum_sum_path(i, j + 1);
// If the position is
// in the last column
else
total_sum = a[i, j] +
maximum_sum_path(i + 1, j);
// Updating the maximum
// sum till the current
// position in the dp
dp[i, j] = total_sum;
// Returning the updated
// maximum value
return total_sum;
}
// Driver Code
public static void Main(String[] args)
{
inputMatrix();
// Calling the implemented function
int maximum_sum = maximum_sum_path(0, 0);
Console.WriteLine(maximum_sum);
}
}
// This code is contributed by shikhasingrajput
输出
3000
时间复杂度: O(N*M)
辅助空间: O(N*M)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。