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:
- 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.
-
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:
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: 7
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,
- Go to cell mat[i + 1][j].
- Go to cell mat[i][j + 1].
- Go to cell mat[i – 1][j] and update S = 1.
-
Case 2: When S = 1 then we have two possible paths,
- Go to cell mat[i – 1][j].
- Go to cell mat[i][j + 1].
Below is the implementation of the above approach:
// 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 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 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# 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..... */ |
<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> |
15