Thursday, December 26, 2024
Google search engine
HomeLanguagesDynamic ProgrammingMaximum sum path in a matrix from top-left to bottom-right

Maximum sum path in a matrix from top-left to bottom-right

Given a matrix mat[][] of dimensions N * M, the task is to find the path from the top-left cell (0, 0) to the bottom-right cell (N – 1, M – 1) of the given matrix such that sum of the elements in the path is maximum. The only moves allowed from any cell (i, j) of the matrix are (i + 1, j) or (i, j + 1).

Examples:

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

Approach 1 (Bottom-Up): The idea is to use Dynamic Programming to solve this problem. The key observation is that the cell grid[i][j] can only be reached from grid[i – 1][j] or grid[i][j – 1]. Therefore, the recurrence relation for this problem is given by the equation:

sum(i, j) = max(sum(i – 1, j), sum(i, j – 1)) + grid[i][j]

  1. Initialize an auxiliary matrix sum[][] of dimensions N * M.
  2. Iterate over the matrix elements and update each cell of the auxiliary matrix sum[][] using the above recurrence relation formed.
  3. After completing the above steps, the value sum[N][M] will contain the maximum sum possible for a path from the top-left corner to the bottom-right corner of the given matrix. Print that sum.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the maximum sum
// path in the grid
int MaximumPath(vector<vector<int> >& 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<vector<int> > sum;
    sum.resize(N + 1,
               vector<int>(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<vector<int> > 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




<script>
 
// JavaScript  program for
//the above approach
 
// Function to find the maximum sum
// path in the grid
function MaximumPath(grid)
{
    // Dimensions of grid[][]
    let N = grid.length;
    let M = grid[0].length;
  
    // Stores maximum sum at each cell
    // sum[i][j] from cell sum[0][0]
    let sum =  new Array(N + 1);
    // Loop to create 2D array using 1D array
    for (var i = 0; i < sum.length; i++) {
        sum[i] = new Array(2);
    }
     
    for (var i = 0; i < sum.length; i++) {
        for (var j = 0; j < sum.length; j++) {
        sum[i][j] = 0;
    }
    }
  
    // Iterate to compute the maximum
    // sum path in the grid
    for (let i = 1; i <= N; i++)
    {
        for (let 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
 
    let grid = [[1, 2], [3, 5]];
  document.write(MaximumPath(grid));
   
  // This code is contributed by souravghosh0416.
</script>


Output: 

9

Time Complexity: O(N * M)
Auxiliary Space: O(N * M)

Approach 2 (Top-Down): We will solve the problem recursively in a top-down manner. We formulate the recurrence based on the two ways of reaching the cell grid[i][j] as follows:

  1. If we move one step towards the right, from the cell grid[i][j-1] or,
  2. If we move one step downwards, from the cell grid[i-1][j].

dp[i][j] = max(dp[i][j-1], dp[i-1][j]) + grid[i][j]

Thus, we need to select the step (between the above two) which gives us the maximum value. Also, we need to add the value present in the cell we step into, i.e. grid[i][j].  As this problem has got the property of overlapping subproblems, we can store the result (memoize) of the subproblems in a 2D matrix (let’s call it dp), in order to avoid repeated computations of the same subproblems. Initially, we set all the cells in the dp table with the value -1, and every time we find an answer to a subproblem we overwrite its result in the respective cell in the dp table. Thus, before computing any subproblem we once check that – if that particular subproblem has been previously solved or not, if it has been solved (i.e. its corresponding cell the dp matrix is not -1) we simple return that value, else we solve it and store the result in the dp table. 

Below is the implementation of the above approach:

C++




#include <bits/stdc++.h>
using namespace std;
 
vector<vector<int> > dp;
 
// Function to find the maximum sum path in the grid
int MaximumPathUtil(int i, int j, vector<vector<int> >& 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<vector<int> >& 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<int> (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<vector<int> > 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


Java




/*package whatever //do not write package name here */
 
import java.io.*;
 
class GFG {
    static int dp [][];
     
    // Function to find the maximum sum path in the grid
    static int MaximumPathUtil(int i, int j, int[][] 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] = Math.max(MaximumPathUtil(i, j-1, grid), MaximumPathUtil(i - 1, j, grid)) +
                            grid[i-1][j-1];
    }
     
    static int MaximumPath(int[][] grid)
    {
        // Dimensions of grid[][]
        int n = grid.length;
        int m = grid[0].length;
     
        // dp table to memoize the subproblem results
        dp = new int[n+1][m+1];
        for(int i=0;i<n+1;i++){
            for(int j=0;j<m+1;j++){
                dp[i][j] = -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
public static void main(String args[])
{
    int[][] 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}};
     
    System.out.println(MaximumPath(grid));
}
 
}


Python3




dp = []
 
# Function to find the maximum sum path in the grid
def MaximumPathUtil(i, j, grid):
 
    global dp
     
    # Base condition
    if (i == 0 or 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
    dp[i][j] = max(MaximumPathUtil(i, j-1, grid), MaximumPathUtil(i - 1, j, grid)) + grid[i-1][j-1]
 
    return dp[i][j]
 
def MaximumPath(grid):
 
    global dp
  
    # Dimensions of grid[][]
    n = len(grid)
    m = len(grid[0])
 
    # dp table to memoize the subproblem results
    dp = [[-1 for i in range(m + 1)] for j in range(n + 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
 
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]]
 
print(MaximumPath(grid))
 
# This code is contributed by shinjanpatra


C#




// C# program to implement above approach
using System;
using System.Collections;
using System.Collections.Generic;
 
class GFG
{
    static int[][] dp;
     
    // Function to find the maximum sum path in the grid
    static int MaximumPathUtil(int i, int j, int[][] 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] = Math.Max(MaximumPathUtil(i, j-1, grid), MaximumPathUtil(i - 1, j, grid)) + grid[i-1][j-1];
    }
     
    static int MaximumPath(int[][] grid)
    {
        // Dimensions of grid[][]
        int n = grid.Length;
        int m = grid[0].Length;
     
        // dp table to memoize the subproblem results
        dp = new int[n+1][];
        for(int i = 0 ; i <= n ; i++){
            dp[i] = new int[m + 1];
        }
 
        for(int i = 0 ; i < n + 1 ; i++){
            for(int j = 0 ; j < m + 1 ; j++){
                dp[i][j] = -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
    public static void Main(string[] args){
 
        int[][] grid = {
            new int[]{3, 7, 9, 2, 7},
            new int[]{9, 8, 3, 5, 5},
            new int[]{1, 7, 9, 8, 6},
            new int[]{3, 8, 6, 4, 9},
            new int[]{6, 3, 9, 7, 8}
        };
     
        Console.WriteLine(MaximumPath(grid));
         
    }
}
 
// This code is contributed by subhamgoyal2014.


Javascript




<script>
 
let dp = [];
 
// Function to find the maximum sum path in the grid
function MaximumPathUtil(i, j, 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] = Math.max(MaximumPathUtil(i, j-1, grid),
                      MaximumPathUtil(i - 1, j, grid)) +
                      grid[i-1][j-1];
}
 
function MaximumPath(grid)
{
    // Dimensions of grid[][]
    let n = grid.length;
    let m = grid[0].length;
 
    // dp table to memoize the subproblem results
    dp = new Array(n+1);
    for(let i = 0; i <= n; i++){
        dp[i] = new Array(m + 1).fill(-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
let 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]];
 
document.write(MaximumPath(grid),"</br>");
 
// This code is contributed by shinjanpatra
</script>


Output: 

67

Time Complexity: O(n*m)
Space Complexity: O(n*m)

Feeling lost in the world of random DSA topics, wasting time without progress? It’s time for a change! Join our DSA course, where we’ll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!

RELATED ARTICLES

Most Popular

Recent Comments