📌  相关文章
📜  通过给定单元格之一的矩阵从左上角到右下角的最大路径和

📅  最后修改于: 2021-09-17 07:18:36             🧑  作者: Mango

给定维度为N * M的矩阵mat[][]和一组大小为Q的单元格坐标 [][]坐标,任务是从左上角单元格(1, 1 )到右下角的单元格(N, M) ,这样路径应该至少包含来自数组坐标 [][2] 的坐标之一。从矩阵的任何单元格(i, j)允许的唯一移动是(i + 1, j)(i, j + 1)

例子:

朴素方法:解决给定问题的最简单方法是生成从矩阵的左上角到右下角单元格的所有可能路径,并打印该路径的单元格的最大总和,其中至少有一个坐标在矩阵中路径位于数组坐标 [][] 中

时间复杂度: O((N + M)!)
辅助空间: O(1)

高效的方法:上述方法也可以通过使用动态规划进行优化。考虑两个矩阵start[][]end[][]使得start[i][j]表示从单元格(1, 1)到单元格(i, j)end[i]的最大路径和[j]表示从单元格(i, j)到单元格(N, M)的最大路径和。因此,对于任何坐标(X,Y),最大路径和可以计算为:

请按照以下步骤解决问题:

  • 初始化两个矩阵,比如维度N*M 的start[][]end[][] ,使得start[i][j]表示从单元格(1, 1)到单元格(i, j )end[i][j]表示从单元格(i, j)到单元格(N, M)的最大路径和。
  • 初始化一个变量,比如ans作为 INT_MIN 存储结果的最大总和。
  • 使用本文中讨论的自底向上方法计算从单元格(1, 1)到每个单元格(i, j)的最大路径和,并将其存储在矩阵start[][] 中
  • 使用本文讨论的自顶向下方法计算从单元格(N, M)到每个单元格(i, j)的最大路径和,并将其存储在矩阵end[][] 中
  • 遍历数组坐标 [][]并对每个坐标(X, Y)更新ans的值作为ans(start[X][Y] + end[X][Y] – mat[X][是])
  • 完成上述步骤后,打印ans的值作为结果的最大和。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Stores the maximum path sum from the
// cell (1, 1) to (N, M)
int start[3][3];
 
// Stores the maximum path sum from the
// cell (j, j) to (N, M)
int ending[3][3];
 
// Function to find the maximum path
// sum from the cell (1, 1) to (N, M)
void calculateStart(int n, int m)
{
    // Traverse the first row
    for (int i = 1; i < m; ++i) {
        start[0][i] += start[0][i - 1];
    }
 
    // Traverse the first column
    for (int i = 1; i < n; ++i) {
        start[i][0] += start[i - 1][0];
    }
 
    // Traverse the matrix
    for (int i = 1; i < n; ++i) {
 
        for (int j = 1; j < m; ++j) {
 
            // Update the value of
            // start[i][j]
            start[i][j] += max(start[i - 1][j],
                               start[i][j - 1]);
        }
    }
}
 
// Function to find the maximum path
// sum from the cell (j, j) to (N, M)
void calculateEnd(int n, int m)
{
    // Traverse the last row
    for (int i = n - 2; i >= 0; --i) {
        ending[i][m - 1] += ending[i + 1][m - 1];
    }
 
    // Traverse the last column
    for (int i = m - 2; i >= 0; --i) {
        ending[n - 1][i] += ending[n - 1][i + 1];
    }
 
    // Traverse the matrix
    for (int i = n - 2; i >= 0; --i) {
 
        for (int j = m - 2; j >= 0; --j) {
 
            // Update the value of
            // ending[i][j]
            ending[i][j] += max(ending[i + 1][j],
                                ending[i][j + 1]);
        }
    }
}
 
// Function to find the maximum path sum
// from the top-left to the bottom right
// cell such that path contains one of
// the cells in the array coordinates[][]
void maximumPathSum(int mat[][3], int n,
                    int m, int q,
                    int coordinates[][2])
{
    // Initialize the start and the
    // end matrices
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            start[i][j] = mat[i][j];
            ending[i][j] = mat[i][j];
        }
    }
 
    // Calculate the start matrix
    calculateStart(n, m);
 
    // Calculate the end matrix
    calculateEnd(n, m);
 
    // Stores the maximum path sum
    int ans = 0;
 
    // Traverse the coordinates
    for (int i = 0; i < q; ++i) {
 
        int X = coordinates[i][0] - 1;
        int Y = coordinates[i][1] - 1;
 
        // Update the value of ans
        ans = max(ans, start[X][Y]
                           + ending[X][Y]
                           - mat[X][Y]);
    }
 
    // Print the resultant maximum
    // sum path value
    cout << ans;
}
 
// Drive Code
int main()
{
 
    int mat[][3] = { { 1, 2, 3 },
                     { 4, 5, 6 },
                     { 7, 8, 9 } };
    int N = 3;
    int M = 3;
    int Q = 2;
    int coordinates[][2] = { { 1, 2 },
                             { 2, 2 } };
 
    maximumPathSum(mat, N, M, Q,
                   coordinates);
}


Java
// Java program for tha above approach
import java.util.*;
 
class GFG{
     
// Stores the maximum path sum from the
// cell (1, 1) to (N, M)
static int start[][] = new int[3][3];
 
// Stores the maximum path sum from the
// cell (j, j) to (N, M)
static int ending[][] = new int[3][3];
 
// Function to find the maximum path
// sum from the cell (1, 1) to (N, M)
static void calculateStart(int n, int m)
{
     
    // Traverse the first row
    for(int i = 1; i < m; ++i)
    {
        start[0][i] += start[0][i - 1];
    }
 
    // Traverse the first column
    for(int i = 1; i < n; ++i)
    {
        start[i][0] += start[i - 1][0];
    }
 
    // Traverse the matrix
    for(int i = 1; i < n; ++i)
    {
        for(int j = 1; j < m; ++j)
        {
             
            // Update the value of
            // start[i][j]
            start[i][j] += Math.max(start[i - 1][j],
                                 start[i][j - 1]);
        }
    }
}
 
// Function to find the maximum path
// sum from the cell (j, j) to (N, M)
static void calculateEnd(int n, int m)
{
     
    // Traverse the last row
    for(int i = n - 2; i >= 0; --i)
    {
        ending[i][m - 1] += ending[i + 1][m - 1];
    }
 
    // Traverse the last column
    for(int i = m - 2; i >= 0; --i)
    {
        ending[n - 1][i] += ending[n - 1][i + 1];
    }
 
    // Traverse the matrix
    for(int i = n - 2; i >= 0; --i)
    {
        for(int j = m - 2; j >= 0; --j)
        {
             
            // Update the value of
            // ending[i][j]
            ending[i][j] += Math.max(ending[i + 1][j],
                                  ending[i][j + 1]);
        }
    }
}
 
// Function to find the maximum path sum
// from the top-left to the bottom right
// cell such that path contains one of
// the cells in the array coordinates[][]
static void maximumPathSum(int mat[][], int n,
                           int m, int q,
                           int coordinates[][])
{
     
    // Initialize the start and the
    // end matrices
    for(int i = 0; i < n; ++i)
    {
        for(int j = 0; j < m; ++j)
        {
            start[i][j] = mat[i][j];
            ending[i][j] = mat[i][j];
        }
    }
 
    // Calculate the start matrix
    calculateStart(n, m);
 
    // Calculate the end matrix
    calculateEnd(n, m);
 
    // Stores the maximum path sum
    int ans = 0;
 
    // Traverse the coordinates
    for(int i = 0; i < q; ++i)
    {
        int X = coordinates[i][0] - 1;
        int Y = coordinates[i][1] - 1;
 
        // Update the value of ans
        ans = Math.max(ans, start[X][Y] +
                           ending[X][Y] -
                           mat[X][Y]);
    }
 
    // Print the resultant maximum
    // sum path value
    System.out.print(ans);
}
 
// Driver Code
public static void main(String[] args)
{
    int mat[][] = { { 1, 2, 3 },
                    { 4, 5, 6 },
                    { 7, 8, 9 } };
    int N = 3;
    int M = 3;
    int Q = 2;
    int coordinates[][] = { { 1, 2 },
                            { 2, 2 } };
 
    maximumPathSum(mat, N, M, Q,
                   coordinates);
}   
}
 
// This code is contributed by code_hunt


Python3
# Python3 program for the above approach
 
# Stores the maximum path sum from the
# cell (1, 1) to (N, M)
start = [[0 for i in range(3)]
            for j in range(3)]
 
# Stores the maximum path sum from the
# cell (j, j) to (N, M)
ending = [[0 for i in range(3)]
             for j in range(3)]
 
# Function to find the maximum path
# sum from the cell (1, 1) to (N, M)
def calculateStart(n, m):
     
    # Traverse the first row
    for i in range(1, m, 1):
        start[0][i] += start[0][i - 1]
 
    # Traverse the first column
    for i in range(1, n, 1):
        start[i][0] += start[i - 1][0]
 
    # Traverse the matrix
    for i in range(1, n, 1):
        for j in range(1, m, 1):
             
            # Update the value of
            # start[i][j]
            start[i][j] += max(start[i - 1][j],
                               start[i][j - 1])
 
# Function to find the maximum path
# sum from the cell (j, j) to (N, M)
def calculateEnd(n, m):
     
    # Traverse the last row
    i = n - 2
     
    while(i >= 0):
        ending[i][m - 1] += ending[i + 1][m - 1]
        i -= 1
 
    # Traverse the last column
    i = m - 2
     
    while(i >= 0):
        ending[n - 1][i] += ending[n - 1][i + 1]
        i -= 1
 
    # Traverse the matrix
    i = n - 2
     
    while(i >= 0):
        j = m - 2
        while(j >= 0):
             
            # Update the value of
            # ending[i][j]
            ending[i][j] += max(ending[i + 1][j],
                                ending[i][j + 1])
            j -= 1
             
        i -= 1
 
# Function to find the maximum path sum
# from the top-left to the bottom right
# cell such that path contains one of
# the cells in the array coordinates[][]
def maximumPathSum(mat, n, m, q, coordinates):
     
    # Initialize the start and the
    # end matrices
    for i in range(n):
        for j in range(m):
            start[i][j] = mat[i][j]
            ending[i][j] = mat[i][j]
 
    # Calculate the start matrix
    calculateStart(n, m)
 
    # Calculate the end matrix
    calculateEnd(n, m)
 
    # Stores the maximum path sum
    ans = 0
 
    # Traverse the coordinates
    for i in range(q):
        X = coordinates[i][0] - 1
        Y = coordinates[i][1] - 1
 
        # Update the value of ans
        ans = max(ans, start[X][Y] +
                      ending[X][Y] -
                         mat[X][Y])
 
    # Print the resultant maximum
    # sum path value
    print(ans)
 
# Driver Code
if __name__ == '__main__':
     
    mat = [ [ 1, 2, 3 ],
            [ 4, 5, 6 ],
            [ 7, 8, 9 ] ]
    N = 3
    M = 3
    Q = 2
     
    coordinates = [ [ 1, 2 ], [ 2, 2 ] ]
 
    maximumPathSum(mat, N, M, Q,coordinates)
 
# This code is contributed by ipg2016107


C#
// C# program for the above approach
using System;
 
class GFG{
 
// Stores the maximum path sum from the
// cell (1, 1) to (N, M)
static int[,] start = new int[3, 3];
 
// Stores the maximum path sum from the
// cell (j, j) to (N, M)
static int[,] ending = new int[3, 3];
 
// Function to find the maximum path
// sum from the cell (1, 1) to (N, M)
static void calculateStart(int n, int m)
{
     
    // Traverse the first row
    for(int i = 1; i < m; ++i)
    {
        start[0, i] += start[0, i - 1];
    }
 
    // Traverse the first column
    for(int i = 1; i < n; ++i)
    {
        start[i, 0] += start[i - 1, 0];
    }
 
    // Traverse the matrix
    for(int i = 1; i < n; ++i)
    {
        for(int j = 1; j < m; ++j)
        {
             
            // Update the value of
            // start[i][j]
            start[i, j] += Math.Max(start[i - 1, j],
                                 start[i, j - 1]);
        }
    }
}
 
// Function to find the maximum path
// sum from the cell (j, j) to (N, M)
static void calculateEnd(int n, int m)
{
     
    // Traverse the last row
    for(int i = n - 2; i >= 0; --i)
    {
        ending[i, m - 1] += ending[i + 1, m - 1];
    }
 
    // Traverse the last column
    for(int i = m - 2; i >= 0; --i)
    {
        ending[n - 1, i] += ending[n - 1, i + 1];
    }
 
    // Traverse the matrix
    for(int i = n - 2; i >= 0; --i)
    {
        for(int j = m - 2; j >= 0; --j)
        {
             
            // Update the value of
            // ending[i][j]
            ending[i, j] += Math.Max(ending[i + 1, j],
                                  ending[i, j + 1]);
        }
    }
}
 
// Function to find the maximum path sum
// from the top-left to the bottom right
// cell such that path contains one of
// the cells in the array coordinates[][]
static void maximumPathSum(int[,] mat, int n,
                           int m, int q,
                           int[,] coordinates)
{
     
    // Initialize the start and the
    // end matrices
    for(int i = 0; i < n; ++i)
    {
        for(int j = 0; j < m; ++j)
        {
            start[i, j] = mat[i, j];
            ending[i, j] = mat[i, j];
        }
    }
 
    // Calculate the start matrix
    calculateStart(n, m);
 
    // Calculate the end matrix
    calculateEnd(n, m);
 
    // Stores the maximum path sum
    int ans = 0;
 
    // Traverse the coordinates
    for(int i = 0; i < q; ++i)
    {
        int X = coordinates[i, 0] - 1;
        int Y = coordinates[i, 1] - 1;
 
        // Update the value of ans
        ans = Math.Max(ans, start[X, Y] +
                           ending[X, Y] -
                           mat[X, Y]);
    }
 
    // Print the resultant maximum
    // sum path value
    Console.Write(ans);
}
 
// Driver Code
public static void Main()
{
    int[,] mat = { { 1, 2, 3 },
                    { 4, 5, 6 },
                    { 7, 8, 9 } };
    int N = 3;
    int M = 3;
    int Q = 2;
    int[,] coordinates = { { 1, 2 },
                            { 2, 2 } };
 
    maximumPathSum(mat, N, M, Q,
                   coordinates);
}
}
 
// This code is contributed by target_2.


Javascript


输出:
27

时间复杂度: O(N * M)
辅助空间: O(N * M)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程