📜  矩阵中的最大求和路径

📅  最后修改于: 2021-05-04 13:39:22             🧑  作者: Mango

给定一个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

方法:使用动态编程以递归的方式解决上述问题。

  1. 在(0,0)的矩阵开头分配一个位置。
  2. 从当前位置检查每个下一个允许的位置,然后选择总和最大的路径。
  3. 注意矩阵的边界,即,如果位置到达最后一行或最后一列,则唯一可能的选择分别是向右或向下。
  4. 使用地图存储所有访问位置的跟踪,并在访问任何(i,j)之前,检查该位置是否已被访问过。
  5. 更新每次递归调用返回的所有可能路径的最大值。
  6. 转到位置到达目标单元格,即(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 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)