Skip to content
Related Articles

Related Articles

Improve Article
Save Article
Like Article

Maximise matrix sum by following the given Path

  • Difficulty Level : Expert
  • Last Updated : 11 May, 2021

Given a 2d-matrix mat[][] consisting of positive integers, the task is to find the maximum score we can reach if we have to go to cell mat[0][N – 1] starting from mat[0][0]. We have to cover the matrix in two phases: 
 

  1. Phase 1: If we are at cell mat[i][j] then we can only go to cells mat[i][j + 1] or mat[i + 1][j] without changing the phase else we can go to cell mat[i – 1][j] and switch to phase 2.
  2. Phase 2: If we are at cell mat[i][j] then we can only go to cells mat[i][j + 1] or mat[i – 1][j]
    We can not go out of bounds and the switching between phases will occur at most once.

Note: We may be able to visit the cells of column in which we switch the phase twice.
Examples: 
 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

Input: mat[][] = { 
{1, 1, 1}, 
{1, 5, 1}, 
{1, 1, 1}} 
Output: 15 
Path: (0, 0) -> (0, 1) -> (1, 1) -> (2, 1) -> (1, 1) -> (0, 1) -> (0, 2) 
Phase 1: (0, 0) -> (0, 1) -> (1, 1) -> (2, 1) 
Phase 2: (2, 1) -> (1, 1) -> (0, 1) -> (0, 2) 
Total score = 1 + 1 + 5 + 1 + 5 + 1 + 1 = 15
Input: mat[][] = { 
{1, 1, 1}, 
{1, 1, 1}, 
{1, 1, 1}} 
Output:
 



 

Prerequisite: Maximum sum path in a matrix from top to bottom.
Approach: This problem can be solved using dynamic programming Let’s suppose we are at the cell mat[i][j] and S is the shrink factor. If its 0, then we are in phase-1 (growing phase) else we are in phase-2 (shrinking phase). Thus, S can take only two values. Set S = 1 as soon as we take a step down. 
dp[i][j][S] will be defined as maximum score we can get if we get from cell mat[i][j] to mat[0][N – 1]. Now, let’s discuss the paths we can take. 
Let us assume we are at cell mat[i][j]
 

  • Case 1: When S = 0 then we have three possible paths, 
    1. Go to cell mat[i + 1][j].
    2. Go to cell mat[i][j + 1].
    3. Go to cell mat[i – 1][j] and update S = 1.
  • Case 2: When S = 1 then we have two possible paths, 
    1. Go to cell mat[i – 1][j].
    2. Go to cell mat[i][j + 1].

Below is the implementation of the above approach: 
 

C++




// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
#define n 3
 
// To store the states of the DP
int dp[n][n][2];
bool v[n][n][2];
 
// Function to return the maximum
// of the three integers
int max(int a, int b, int c)
{
    int m = a;
    if (m < b)
        m = b;
    if (m < c)
        m = c;
    return m;
}
 
// Function to return the maximum score
int maxScore(int arr[][n], int i, int j, int s)
{
    // Base cases
    if (i > n - 1 || i < 0 || j > n - 1)
        return 0;
    if (i == 0 and j == n - 1)
        return arr[i][j];
 
    // If the state has already
    // been solved then return it
    if (v[i][j][s])
        return dp[i][j][s];
 
    // Marking the state as solved
    v[i][j][s] = 1;
 
    // Growing phase
    if (!s)
        dp[i][j][s] = arr[i][j] + max(maxScore(arr, i + 1, j, s),
                                      maxScore(arr, i, j + 1, s),
                                      maxScore(arr, i - 1, j, !s));
 
    // Shrinking phase
    else
        dp[i][j][s] = arr[i][j] + max(maxScore(arr, i - 1, j, s),
                                      maxScore(arr, i, j + 1, s));
 
    // Returning the solved state
    return dp[i][j][s];
}
 
// Driver code
int main()
{
    int arr[n][n] = { { 1, 1, 1 },
                      { 1, 5, 1 },
                      { 1, 1, 1 } };
 
    cout << maxScore(arr, 0, 0, 0);
    return 0;
}

Java




// Java implementation of the approach
class GFG
{
 
    static int n = 3;
 
    // To store the states of the DP
    static int[][][] dp = new int[n][n][2];
    static boolean[][][] v = new boolean[n][n][2];
 
    // Function to return the maximum
    // of the three integers
    static int max(int a, int b, int c)
     
    {
        int m = a;
        if (m < b)
        {
            m = b;
        }
        if (m < c)
        {
            m = c;
        }
        return m;
    }
 
// Function to return the maximum score
    static int maxScore(int arr[][], int i, int j, int s)
    {
        // Base cases
        if (i > n - 1 || i < 0 || j > n - 1)
        {
            return 0;
        }
        if (i == 0 && j == n - 1)
        {
            return arr[i][j];
        }
 
        // If the state has already
        // been solved then return it
        if (v[i][j][s])
         
         
        {
            return dp[i][j][s];
        }
 
        // Marking the state as solved
        v[i][j][s] = true;
 
        // Growing phase
        if (s != 1)
        {
            dp[i][j][s] = arr[i][j] + Math.max(maxScore(arr, i + 1, j, s),
                                    Math.max(maxScore(arr, i, j + 1, s),
                                    maxScore(arr, i - 1, j, (s==1)?0:1)));
        } // Shrinking phase
        else
        {
            dp[i][j][s] = arr[i][j] + Math.max(maxScore(arr, i - 1, j, s),
                    maxScore(arr, i, j + 1, s));
        }
 
        // Returning the solved state
        return dp[i][j][s];
    }
 
    // Driver code
    public static void main(String args[])
    {
        int arr[][] = {{1, 1, 1},
        {1, 5, 1},
        {1, 1, 1}};
 
        System.out.println(maxScore(arr, 0, 0, 0));
 
    }
}
 
/* This code contributed by PrinciRaj1992 */

Python3




# Python3 implementation of the approach
import numpy as np
 
n = 3
 
# To store the states of the DP
dp = np.zeros((n,n,2));
v = np.zeros((n,n,2));
 
# Function to return the maximum
# of the three integers
def max_three(a, b, c) :
 
    m = a;
    if (m < b) :
        m = b;
         
    if (m < c) :
        m = c;
         
    return m;
 
 
# Function to return the maximum score
def maxScore(arr, i, j, s) :
 
    # Base cases
    if (i > n - 1 or i < 0 or j > n - 1) :
        return 0;
         
    if (i == 0 and j == n - 1) :
        return arr[i][j];
 
    # If the state has already
    # been solved then return it
    if (v[i][j][s]) :
        return dp[i][j][s];
 
    # Marking the state as solved
    v[i][j][s] = 1;
 
    # Growing phase
    if (not bool(s)) :
        dp[i][j][s] = arr[i][j] + max_three(maxScore(arr, i + 1, j, s),
                                    maxScore(arr, i, j + 1, s),
                                    maxScore(arr, i - 1, j, not bool(s)));
 
    # Shrinking phase
    else :
        dp[i][j][s] = arr[i][j] + max(maxScore(arr, i - 1, j, s),
                                    maxScore(arr, i, j + 1, s));
 
    # Returning the solved state
    return dp[i][j][s];
 
 
# Driver code
if __name__ == "__main__" :
 
    arr = [ [ 1, 1, 1 ],
                    [ 1, 5, 1 ],
                    [ 1, 1, 1 ] ,
                    ];
 
    print(maxScore(arr, 0, 0, 0));
     
# This code is contributed by AnkitRai01

C#




// C# implementation of the approach
using System;
 
class GFG
{
 
    static int n = 3;
     
    // To store the states of the DP
    static int[,,] dp = new int[n,n,2];
    static bool[,,] v = new bool[n,n,2];
 
    // Function to return the maximum
    // of the three integers
    static int max(int a, int b, int c)
     
    {
        int m = a;
        if (m < b)
        {
            m = b;
        }
        if (m < c)
        {
            m = c;
        }
        return m;
    }
 
    // Function to return the maximum score
    static int maxScore(int [,]arr, int i, int j, int s)
    {
        // Base cases
        if (i > n - 1 || i < 0 || j > n - 1)
        {
            return 0;
        }
        if ((i == 0) && (j == (n - 1)))
        {
            return arr[i, j];
        }
 
        // If the state has already
        // been solved then return it
        if (v[i, j, s])
         
         
        {
            return dp[i, j, s];
        }
 
        // Marking the state as solved
        v[i, j, s] = true;
 
        // Growing phase
        if (s != 1)
        {
            dp[i,j,s] = arr[i,j] + Math.Max(maxScore(arr, i + 1, j, s),
                                    Math.Max(maxScore(arr, i, j + 1, s),
                                    maxScore(arr, i - 1, j, (s==1)?0:1)));
        } // Shrinking phase
        else
        {
            dp[i,j,s] = arr[i,j] + Math.Max(maxScore(arr, i - 1, j, s),
                    maxScore(arr, i, j + 1, s));
        }
 
        // Returning the solved state
        return dp[i, j, s];
    }
 
    // Driver code
    static public void Main ()
    {
        int [,]arr = {{1, 1, 1},
        {1, 5, 1},
        {1, 1, 1}};
 
        Console.WriteLine(maxScore(arr, 0, 0, 0));
    }
}
 
/* This code contributed by @Tushil..... */

Javascript




<script>
    // Javascript implementation of the approach
     
    let n = 3;
   
    // To store the states of the DP
    let dp = new Array(n);
    let v = new Array(n);
     
    for(let i = 0; i < n; i++)
    {
        dp[i] = new Array(n);
        v[i] = new Array(n);
        for(let j = 0; j < n; j++)
        {
            dp[i][j] = new Array(2);
            v[i][j] = new Array(2);
            for(let k = 0; k < 2; k++)
            {
                dp[i][j][k] = 0;
                v[i][j][k] = 0;
            }
        }
    }
   
    // Function to return the maximum
    // of the three integers
    function max(a, b, c)
       
    {
        let m = a;
        if (m < b)
        {
            m = b;
        }
        if (m < c)
        {
            m = c;
        }
        return m;
    }
   
    // Function to return the maximum score
    function maxScore(arr, i, j, s)
    {
        // Base cases
        if (i > n - 1 || i < 0 || j > n - 1)
        {
            return 0;
        }
        if (i == 0 && j == n - 1)
        {
            return arr[i][j];
        }
   
        // If the state has already
        // been solved then return it
        if (v[i][j][s])
           
           
        {
            return dp[i][j][s];
        }
   
        // Marking the state as solved
        v[i][j][s] = true;
   
        // Growing phase
        if (s != 1)
        {
            dp[i][j][s] = arr[i][j] + Math.max(maxScore(arr, i + 1, j, s),
                                    Math.max(maxScore(arr, i, j + 1, s),
                                    maxScore(arr, i - 1, j, (s==1)?0:1)));
        } // Shrinking phase
        else
        {
            dp[i][j][s] = arr[i][j] + Math.max(maxScore(arr, i - 1, j, s),
                    maxScore(arr, i, j + 1, s));
        }
   
        // Returning the solved state
        return dp[i][j][s];
    }
     
    let arr = [[1, 1, 1],
               [1, 5, 1],
               [1, 1, 1]];
 
    document.write(maxScore(arr, 0, 0, 0));
 
</script>
Output: 
15

 




My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!