Paths from entry to exit in matrix and maximum path sum

Given a maze which is a N * N grid grid[][]. Every cell of the maze contains either the number 1, 2 or 3 which defines the moves as:

  • If grid[i][j] = 1 then the only valid move is grid[i][j + 1].
  • If grid[i][j] = 2 then the only valid move is grid[i + 1][j].
  • If grid[i][j] = 3 then the valid moves are grid[i][j + 1] and grid[i + 1][j].

Now, the task is to find the count of all the paths from grid[0][0] to grid[N – 1][N – 1] and the maximum possible sum among all the paths i.e. when all the values at the visited cells are added to the sum.

Examples:



Input: grid[][] = {
{3, 2},
{3, 1}}
Output:
Total paths: 2
Maximum sum: 7
The two valid paths are
(0, 0) -> (0, 1) -> (1, 1) with sum as 3 + 2 + 1 = 6
and (0, 0) -> (1, 0) -> (1, 1) with sum as 3 + 3 + 1 = 7

Input: grid[][] = {
{1, 1, 3, 2, 1},
{3, 2, 2, 1, 2},
{1, 3, 3, 1, 3},
{1, 2, 3, 1, 2},
{1, 1, 1, 3, 1}}
Output:
Total paths: 4
Maximum sum: 18

Approach: This problem can be solved using dynamic programming.
To count the number of paths, create a dp[][] array where dp[i][j] will store the count of paths from grid[i][j] to grid[N – 1][N – 1] and the recurrence relation will be,

  1. If grid[i][j] = 1 then dp[i][j] = dp[i][j + 1].
  2. If grid[i][j] = 2 then dp[i][j] = dp[i + 1][j].
  3. If grid[i][j] = 1 then dp[i][j] = dp[i][j + 1] + dp[i + 1][j].

and the termination condition will be when source and destination are same i.e. dp[N – 1][N – 1] = 1.

Now, to find the maximum sum path, another dp[][] array can be created where dp[i][j] will store the maximum sum of the path from grid[i][j] to grid[N – 1][N – 1] and the recurrence relation will be,

  1. If grid[i][j] = 1 then dp[i][j] = grid[i][j] + dp[i][j + 1].
  2. If grid[i][j] = 2 then dp[i][j] = grid[i][j] + dp[i + 1][j].
  3. If grid[i][j] = 1 then dp[i][j] = grid[i][j] + max(dp[i][j + 1] + dp[i + 1][j]).

and the termination condition will again be when source and destination are same i.e. dp[N – 1][N – 1] = grid[N – 1][N – 1].

Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach
import java.util.Arrays;
  
class GFG {
  
    // Recursive function to return the total
    // paths from grid[i][j] to grid[n - 1][n - 1]
    static int totalPaths(int i, int j, int n, int grid[][], int dp[][])
    {
  
        // Out of bounds
        if (i < 0 || j < 0 || i >= n || j >= n)
            return 0;
  
        // If the current state hasn't been solved before
        if (dp[i][j] == -1) {
  
            // Only valid move is right
            if (grid[i][j] == 1)
                dp[i][j] = totalPaths(i, j + 1, n, grid, dp);
  
            // Only valid move is down
            else if (grid[i][j] == 2)
                dp[i][j] = totalPaths(i + 1, j, n, grid, dp);
  
            // Right and down, both are valid moves
            else
                dp[i][j] = totalPaths(i, j + 1, n, grid, dp)
                           + totalPaths(i + 1, j, n, grid, dp);
        }
        return dp[i][j];
    }
  
    // Recursive function to return the maximum
    // sum along the path from grid[i][j] to grid[n - 1][n - 1]
    static int maxSumPath(int i, int j, int n, int grid[][], int dp[][])
    {
  
        // Out of bounds
        if (i < 0 || j < 0 || i >= n || j >= n)
            return 0;
  
        // If the current state hasn't been solved before
        if (dp[i][j] == -1) {
  
            // Only valid move is right
            if (grid[i][j] == 1)
                dp[i][j] = grid[i][j] + maxSumPath(i, j + 1, n, grid, dp);
  
            // Only valid move is down
            else if (grid[i][j] == 2)
                dp[i][j] = grid[i][j] + maxSumPath(i + 1, j, n, grid, dp);
  
            // Right and down, both are valid moves
            else
                dp[i][j] = grid[i][j]
                           + Math.max(maxSumPath(i, j + 1, n, grid, dp),
                                      maxSumPath(i + 1, j, n, grid, dp));
        }
        return dp[i][j];
    }
  
    // Driver code
    public static void main(String[] args)
    {
        int grid[][] = { { 1, 1, 3, 2, 1 },
                         { 3, 2, 2, 1, 2 },
                         { 1, 3, 3, 1, 3 },
                         { 1, 2, 3, 1, 2 },
                         { 1, 1, 1, 3, 1 } };
        int n = grid.length;
  
        // Fill the dp[][] array with -1
        int dp[][] = new int[n][n];
        for (int i = 0; i < n; i++)
            Arrays.fill(dp[i], -1);
  
        // When source and destination are same
        // then there is only 1 path
        dp[n - 1][n - 1] = 1;
  
        // Print the count of paths from
        // grid[0][0] to grid[n - 1][n - 1]
        System.out.println("Total paths: "
                           + totalPaths(0, 0, n, grid, dp));
  
        // Fill the dp[][] array again with -1
        for (int i = 0; i < n; i++)
            Arrays.fill(dp[i], -1);
  
        // When source and destination are same
        // then the sum is grid[n - 1][n - 1]
        dp[n - 1][n - 1] = grid[n - 1][n - 1];
  
        // Print the maximum sum among all the paths
        // from grid[0][0] to grid[n - 1][n - 1]
        System.out.println("Maximum sum: "
                           + maxSumPath(0, 0, n, grid, dp));
    }
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of the approach 
  
# Recursive function to return the total 
# paths from grid[i][j] to grid[n - 1][n - 1] 
def totalPaths(i, j, n, grid, dp): 
  
    # Out of bounds 
    if (i < 0 or j < 0 or i >= n or j >= n): 
        return 0
  
    # If the current state 
    # hasn't been solved before 
    if (dp[i][j] == -1): 
      
        # Only valid move is right 
        if (grid[i][j] == 1): 
            dp[i][j] = totalPaths(i, j + 1, n, grid, dp) 
  
        # Only valid move is down 
        elif (grid[i][j] == 2): 
            dp[i][j] = totalPaths(i + 1, j, n, grid, dp) 
  
        # Right and down, both are valid moves 
        else:
            dp[i][j] = totalPaths(i, j + 1, n, grid, dp) +\
                       totalPaths(i + 1, j, n, grid, dp) 
      
    return dp[i][j] 
  
# Recursive function to return the maximum 
# sum along the path from grid[i,j] to grid[n - 1,n - 1] 
def maxSumPath(i, j, n, grid, dp): 
  
    # Out of bounds 
    if (i < 0 or j < 0 or i >= n or j >= n): 
        return 0
  
    # If the current state 
    # hasn't been solved before 
    if (dp[i][j] == -1): 
      
        # Only valid move is right 
        if (grid[i][j] == 1): 
            dp[i][j] = grid[i][j] + \
                       maxSumPath(i, j + 1, n, grid, dp) 
  
        # Only valid move is down 
        elif (grid[i][j] == 2): 
            dp[i][j] = grid[i][j] + \
                       maxSumPath(i + 1, j, n, grid, dp) 
  
        # Right and down, both are valid moves 
        else:
            dp[i][j] = grid[i][j] + \
                       max(maxSumPath(i, j + 1, n, grid, dp), 
                           maxSumPath(i + 1, j, n, grid, dp)) 
      
    return dp[i][j] 
  
# Driver code 
if __name__ == '__main__':
      
    grid = [[ 1, 1, 3, 2, 1 ], 
            [ 3, 2, 2, 1, 2 ], 
            [ 1, 3, 3, 1, 3 ], 
            [ 1, 2, 3, 1, 2 ], 
            [ 1, 1, 1, 3, 1 ]]
  
    n = len(grid[0])
  
    # Fill the dp[n][n] array with -1
    dp= [[-1] * n] *
  
    # When source and destination are same 
    # then there is only 1 path 
    dp[n - 1][n - 1] = 1
  
    # Print the count of paths from 
    # grid[0,0] to grid[n - 1][n - 1] 
    print("Total paths:"
           totalPaths(0, 0, n, grid, dp)) 
  
    # Fill the dp[n][n] array again with -1 
    dp= [[-1] * n] *
  
    # When source and destination are same 
    # then the sum is grid[n - 1][n - 1] 
    dp[n - 1][n - 1] = grid[n - 1][n - 1
  
    # Print the maximum sum among all the paths 
    # from grid[0,0] to grid[n - 1][n - 1] 
    print("Maximum sum:"
           maxSumPath(0, 0, n, grid, dp)) 
  
# This code is contributed by ashutosh450 

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the approach
using System;
  
class GFG 
{
  
// Recursive function to return the total
// paths from grid[i][j] to grid[n - 1][n - 1]
static int totalPaths(int i, int j, int n, 
                      int [,]grid, int [,]dp)
{
  
    // Out of bounds
    if (i < 0 || j < 0 || i >= n || j >= n)
        return 0;
  
    // If the current state
    // hasn't been solved before
    if (dp[i, j] == -1)
    {
  
        // Only valid move is right
        if (grid[i, j] == 1)
            dp[i, j] = totalPaths(i, j + 1, n, grid, dp);
  
        // Only valid move is down
        else if (grid[i, j] == 2)
            dp[i, j] = totalPaths(i + 1, j, n, grid, dp);
  
        // Right and down, both are valid moves
        else
            dp[i, j] = totalPaths(i, j + 1, n, grid, dp) + 
                      totalPaths(i + 1, j, n, grid, dp);
    }
    return dp[i, j];
}
  
// Recursive function to return the maximum
// sum along the path from grid[i,j] to grid[n - 1,n - 1]
static int maxSumPath(int i, int j, int n,
                      int [,]grid, int [,]dp)
{
  
    // Out of bounds
    if (i < 0 || j < 0 || i >= n || j >= n)
        return 0;
  
    // If the current state 
    // hasn't been solved before
    if (dp[i, j] == -1) 
    {
  
        // Only valid move is right
        if (grid[i, j] == 1)
            dp[i, j] = grid[i, j] + maxSumPath(i, j + 1, 
                                               n, grid, dp);
  
        // Only valid move is down
        else if (grid[i,j] == 2)
            dp[i, j] = grid[i, j] + maxSumPath(i + 1, j,
                                               n, grid, dp);
  
        // Right and down, both are valid moves
        else
            dp[i, j] = grid[i, j] + 
                       Math.Max(maxSumPath(i, j + 1, n, grid, dp), 
                                maxSumPath(i + 1, j, n, grid, dp));
    }
    return dp[i, j];
}
  
// Driver code
public static void Main(String[] args)
{
    int [,]grid = { { 1, 1, 3, 2, 1 },
                    { 3, 2, 2, 1, 2 },
                    { 1, 3, 3, 1, 3 },
                    { 1, 2, 3, 1, 2 },
                    { 1, 1, 1, 3, 1 } };
    int n = grid.GetLength(0);
  
    // Fill the dp[,] array with -1
    int [,]dp = new int[n, n];
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            dp[i, j] = -1;
  
    // When source and destination are same
    // then there is only 1 path
    dp[n - 1, n - 1] = 1;
  
    // Print the count of paths from
    // grid[0,0] to grid[n - 1,n - 1]
    Console.WriteLine("Total paths: "
                       totalPaths(0, 0, n, grid, dp));
  
    // Fill the dp[,] array again with -1
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            dp[i, j] = -1;
  
    // When source and destination are same
    // then the sum is grid[n - 1,n - 1]
    dp[n - 1, n - 1] = grid[n - 1, n - 1];
  
    // Print the maximum sum among all the paths
    // from grid[0,0] to grid[n - 1,n - 1]
    Console.WriteLine("Maximum sum: "
                       maxSumPath(0, 0, n, grid, dp));
}
}
  
// This code is contributed by Princi Singh

chevron_right


Output:

Total paths: 4
Maximum sum: 18

Time complexity: O(n2)
Space complexity: O(n2)



My Personal Notes arrow_drop_up

Competitive Programmer, Full Stack Developer, Technical Content Writer, Machine Learner

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : princi singh, ashutosh450