Given a gold mine of n*m dimensions. Each field in this mine contains a positive integer which is the amount of gold in tons. Initially, the miner is in the first column but can be in any row. He can move only (right->,right up /,right down\) that is from a given cell, the miner can move to the cell diagonally up towards the right or diagonally down towards the right. Find out the maximum amount of gold he can collect.
Examples:
Input : mat[][] = {{1, 3, 3},
{2, 1, 4},
{0, 6, 4}};
Output : 12
{(1,0)->(2,1)->(1,2)}
Input: mat[][] = { {1, 3, 1, 5},
{2, 2, 4, 1},
{5, 0, 2, 3},
{0, 6, 1, 2}};
Output : 16
(2,0) -> (1,1) -> (1,2) -> (0,3) OR
(2,0) -> (3,1) -> (2,2) -> (2,3)
Input : mat[][] = {{10, 33, 13, 15},
{22, 21, 04, 1},
{5, 0, 2, 3},
{0, 6, 14, 2}};
Output : 83
Source Flipkart Interview
Method 1: Recursion
A simple method that is a direct recursive implementation
C++
#include<bits/stdc++.h>
using namespace std;
int collectGold(vector<vector< int >> gold, int x, int y, int n, int m) {
if ((x < 0) || (x == n) || (y == m)) {
return 0;
}
int rightUpperDiagonal = collectGold(gold, x - 1, y + 1, n, m);
int right = collectGold(gold, x, y + 1, n, m);
int rightLowerDiagonal = collectGold(gold, x + 1, y + 1, n, m);
return gold[x][y] + max(max(rightUpperDiagonal, rightLowerDiagonal), right);
}
int getMaxGold(vector<vector< int >> gold, int n, int m)
{
int maxGold = 0;
for ( int i = 0; i < n; i++) {
int goldCollected = collectGold(gold, i, 0, n, m);
maxGold = max(maxGold, goldCollected);
}
return maxGold;
}
int main()
{
vector<vector< int >> gold { {1, 3, 1, 5},
{2, 2, 4, 1},
{5, 0, 2, 3},
{0, 6, 1, 2}
};
int m = 4, n = 4;
cout << getMaxGold(gold, n, m);
return 0;
}
|
Java
import java.io.*;
class GFG {
static int collectGold( int [][] gold, int x, int y,
int n, int m)
{
if ((x < 0 ) || (x == n) || (y == m)) {
return 0 ;
}
int rightUpperDiagonal
= collectGold(gold, x - 1 , y + 1 , n, m);
int right = collectGold(gold, x, y + 1 , n, m);
int rightLowerDiagonal
= collectGold(gold, x + 1 , y + 1 , n, m);
return gold[x][y]
+ Math.max(Math.max(rightUpperDiagonal,
rightLowerDiagonal),
right);
}
static int getMaxGold( int [][] gold, int n, int m)
{
int maxGold = 0 ;
for ( int i = 0 ; i < n; i++) {
int goldCollected
= collectGold(gold, i, 0 , n, m);
maxGold = Math.max(maxGold, goldCollected);
}
return maxGold;
}
public static void main(String[] args)
{
int [][] gold = { { 1 , 3 , 1 , 5 },
{ 2 , 2 , 4 , 1 },
{ 5 , 0 , 2 , 3 },
{ 0 , 6 , 1 , 2 } };
int m = 4 , n = 4 ;
System.out.println(getMaxGold(gold, n, m));
}
}
|
Python3
def collectGold(gold, x, y, n, m):
if ((x < 0 ) or (x = = n) or (y = = m)):
return 0
rightUpperDiagonal = collectGold(gold, x - 1 , y + 1 , n, m)
right = collectGold(gold, x, y + 1 , n, m)
rightLowerDiagonal = collectGold(gold, x + 1 , y + 1 , n, m)
return gold[x][y] + max ( max (rightUpperDiagonal, rightLowerDiagonal), right)
def getMaxGold(gold,n,m):
maxGold = 0
for i in range (n):
goldCollected = collectGold(gold, i, 0 , n, m)
maxGold = max (maxGold, goldCollected)
return maxGold
gold = [[ 1 , 3 , 1 , 5 ],
[ 2 , 2 , 4 , 1 ],
[ 5 , 0 , 2 , 3 ],
[ 0 , 6 , 1 , 2 ]
]
m,n = 4 , 4
print (getMaxGold(gold, n, m))
|
C#
using System;
public class GFG{
static public int collectGold( int [,] gold, int x,
int y, int n, int m)
{
if ((x < 0) || (x == n) || (y == m)) {
return 0;
}
int rightUpperDiagonal = collectGold(gold, x - 1, y + 1, n, m);
int right = collectGold(gold, x, y + 1, n, m);
int rightLowerDiagonal = collectGold(gold, x + 1, y + 1, n, m);
return gold[x,y] + Math.Max(Math.Max(rightUpperDiagonal,
rightLowerDiagonal), right);
}
static public int getMaxGold( int [,] gold, int n, int m){
int maxGold = 0;
for ( int i = 0; i < n; i++) {
int goldCollected = collectGold(gold, i, 0, n, m);
maxGold = Math.Max(maxGold, goldCollected);
}
return maxGold;
}
static public void Main (){
int [,] gold = new int [,] { { 1, 3, 1, 5 },
{ 2, 2, 4, 1 },
{ 5, 0, 2, 3 },
{ 0, 6, 1, 2 } };
int m = 4, n = 4;
Console.Write(getMaxGold(gold, n, m));
}
}
|
Javascript
<script>
function collectGold(gold,x,y,n,m) {
if ((x < 0) || (x == n) || (y == m)) {
return 0;
}
let rightUpperDiagonal = collectGold(gold, x - 1, y + 1, n, m);
let right = collectGold(gold, x, y + 1, n, m);
let rightLowerDiagonal = collectGold(gold, x + 1, y + 1, n, m);
return gold[x][y] + Math.max(Math.max(rightUpperDiagonal, rightLowerDiagonal), right);
}
function getMaxGold(gold,n,m)
{
maxGold = 0;
for (i = 0; i < n; i++) {
goldCollected = collectGold(gold, i, 0, n, m);
maxGold = Math.max(maxGold, goldCollected);
}
return maxGold;
}
let gold = [[1, 3, 1, 5],
[2, 2, 4, 1],
[5, 0, 2, 3],
[0, 6, 1, 2]
];
let m = 4, n = 4;
document.write(getMaxGold(gold, n, m));
</script>
|
Time complexity: O(3N*M)
Auxiliary Space: O(N*M)
Method 2: Memoization
Bottom-Up Approach: The second way is to take an extra space of size m*n and start computing values of states of right, right upper diagonal, and right bottom diagonal and store it in the 2d array.
C++
#include<bits/stdc++.h>
using namespace std;
int collectGold(vector<vector< int >> gold, int x, int y, int n, int m, vector<vector< int >> &dp) {
if ((x < 0) || (x == n) || (y == m)) {
return 0;
}
if (dp[x][y] != -1){
return dp[x][y] ;
}
int rightUpperDiagonal = collectGold(gold, x - 1, y + 1, n, m, dp);
int right = collectGold(gold, x, y + 1, n, m, dp);
int rightLowerDiagonal = collectGold(gold, x + 1, y + 1, n, m, dp);
return dp[x][y] = gold[x][y] + max(max(rightUpperDiagonal, rightLowerDiagonal), right);
}
int getMaxGold(vector<vector< int >> gold, int n, int m)
{
int maxGold = 0;
vector<vector< int >> dp(n, vector< int >(m, -1)) ;
for ( int i = 0; i < n; i++) {
int goldCollected = collectGold(gold, i, 0, n, m, dp);
maxGold = max(maxGold, goldCollected);
}
return maxGold;
}
int main()
{
vector<vector< int >> gold { {1, 3, 1, 5},
{2, 2, 4, 1},
{5, 0, 2, 3},
{0, 6, 1, 2}
};
int m = 4, n = 4;
cout << getMaxGold(gold, n, m);
return 0;
}
|
Java
import java.io.*;
class Gold {
static int collectGold( int [][] gold, int x, int y,
int n, int m, int [][] dp)
{
if ((x < 0 ) || (x == n) || (y == m)) {
return 0 ;
}
if (dp[x][y] != - 1 ) {
return dp[x][y];
}
int rightUpperDiagonal
= collectGold(gold, x - 1 , y + 1 , n, m, dp);
int right = collectGold(gold, x, y + 1 , n, m, dp);
int rightLowerDiagonal
= collectGold(gold, x + 1 , y + 1 , n, m, dp);
return dp[x][y] = gold[x][y]
+ Math.max(Math.max(rightUpperDiagonal,
rightLowerDiagonal),
right);
}
static int getMaxGold( int [][] gold, int n, int m)
{
int maxGold = 0 ;
int [][] dp = new int [n][m];
for ( int row = 0 ; row < n; row++) {
Arrays.fill(dp[row], - 1 );
}
for ( int i = 0 ; i < n; i++) {
int goldCollected
= collectGold(gold, i, 0 , n, m, dp);
maxGold = Math.max(maxGold, goldCollected);
}
return maxGold;
}
public static void main(String[] args)
{
int [][] gold = { { 1 , 3 , 1 , 5 },
{ 2 , 2 , 4 , 1 },
{ 5 , 0 , 2 , 3 },
{ 0 , 6 , 1 , 2 } };
int m = 4 , n = 4 ;
System.out.println(getMaxGold(gold, n, m));
}
}
|
Python3
def collectGold(gold, x, y, n, m, dp):
if ((x < 0 ) or (x = = n) or (y = = m)):
return 0
if (dp[x][y] ! = - 1 ):
return dp[x][y]
rightUpperDiagonal = collectGold(gold, x - 1 , y + 1 , n, m, dp)
right = collectGold(gold, x, y + 1 , n, m, dp)
rightLowerDiagonal = collectGold(gold, x + 1 , y + 1 , n, m, dp)
dp[x][y] = gold[x][y] + max ( max (rightUpperDiagonal, rightLowerDiagonal), right)
return dp[x][y]
def getMaxGold(gold,n,m):
maxGold = 0
dp = [[ - 1 for i in range (m)] for j in range (n)]
for i in range (n):
goldCollected = collectGold(gold, i, 0 , n, m, dp)
maxGold = max (maxGold, goldCollected)
return maxGold
gold = [ [ 1 , 3 , 1 , 5 ],
[ 2 , 2 , 4 , 1 ],
[ 5 , 0 , 2 , 3 ],
[ 0 , 6 , 1 , 2 ] ]
m,n = 4 , 4
print (getMaxGold(gold, n, m))
|
C#
using System;
public class Gold
{
static int collectGold( int [,] gold, int x, int y,
int n, int m, int [,] dp)
{
if ((x < 0) || (x == n) || (y == m))
{
return 0;
}
if (dp[x,y] != -1)
{
return dp[x,y];
}
int rightUpperDiagonal = collectGold(gold, x - 1, y + 1, n, m, dp);
int right = collectGold(gold, x, y + 1, n, m, dp);
int rightLowerDiagonal = collectGold(gold, x + 1, y + 1, n, m, dp);
return gold[x,y] + Math.Max(Math.Max(rightUpperDiagonal,
rightLowerDiagonal), right);
}
static int getMaxGold( int [,] gold, int n, int m)
{
int maxGold = 0;
int [,] dp = new int [n, m];
for ( int row = 0; row < n; row++)
{
for ( int col = 0; col < m; col++)
{
dp[row,col] = -1;
}
}
for ( int i = 0; i < n; i++)
{
int goldCollected = collectGold(gold, i, 0, n, m, dp);
maxGold = Math.Max(maxGold, goldCollected);
}
return maxGold;
}
static public void Main ()
{
int [,] gold = { { 1, 3, 1, 5 },
{ 2, 2, 4, 1 },
{ 5, 0, 2, 3 },
{ 0, 6, 1, 2 } };
int m = 4, n = 4;
Console.Write(getMaxGold(gold, n, m));
}
}
|
Javascript
<script>
function collectGold(gold, x, y, n, m, dp)
{
if ((x < 0) || (x == n) || (y == m)) {
return 0;
}
if (dp[x][y] != -1){
return dp[x][y] ;
}
let rightUpperDiagonal = collectGold(gold, x - 1, y + 1, n, m, dp);
let right = collectGold(gold, x, y + 1, n, m, dp);
let rightLowerDiagonal = collectGold(gold, x + 1, y + 1, n, m, dp);
return dp[x][y] = gold[x][y] + Math.max(Math.max(rightUpperDiagonal, rightLowerDiagonal), right);
}
function getMaxGold(gold,n,m)
{
let maxGold = 0;
let dp = new Array(n);
for (let i = 0; i < n; i++)
{
dp[i] = new Array(m).fill(-1);
}
for (let i = 0; i < n; i++)
{
let goldCollected = collectGold(gold, i, 0, n, m, dp);
maxGold = Math.max(maxGold, goldCollected);
}
return maxGold;
}
let gold = [ [1, 3, 1, 5],
[2, 2, 4, 1],
[5, 0, 2, 3],
[0, 6, 1, 2] ];
let m = 4, n = 4;
document.write(getMaxGold(gold, n, m));
</script>
|
Time Complexity: O(m*n)
Auxiliary Space: O(m*n)
Method 3: Using Dp, Tabulation
Create a 2-D matrix goldTable[][]) of the same as given matrix mat[][]. If we observe the question closely, we can notice following.
- Amount of gold is positive, so we would like to cover maximum cells of maximum values under given constraints.
- In every move, we move one step toward right side. So we always end up in last column. If we are at the last column, then we are unable to move right
If we are at the first row or last column, then we are unable to move right-up so just assign 0 otherwise assign the value of goldTable[row-1][col+1] to right_up. If we are at the last row or last column, then we are unable to move right down so just assign 0 otherwise assign the value of goldTable[row+1][col+1] to right up.
Now find the maximum of right, right_up, and right_down and then add it with that mat[row][col]. At last, find the maximum of all rows and first column and return it.
C++
#include<bits/stdc++.h>
using namespace std;
const int MAX = 100;
int getMaxGold( int gold[][MAX], int m, int n)
{
int goldTable[m][n];
memset (goldTable, 0, sizeof (goldTable));
for ( int col=n-1; col>=0; col--)
{
for ( int row=0; row<m; row++)
{
int right = (col==n-1)? 0: goldTable[row][col+1];
int right_up = (row==0 || col==n-1)? 0:
goldTable[row-1][col+1];
int right_down = (row==m-1 || col==n-1)? 0:
goldTable[row+1][col+1];
goldTable[row][col] = gold[row][col] +
max(right, max(right_up, right_down));
}
}
int res = goldTable[0][0];
for ( int i=1; i<m; i++)
res = max(res, goldTable[i][0]);
return res;
}
int main()
{
int gold[MAX][MAX]= { {1, 3, 1, 5},
{2, 2, 4, 1},
{5, 0, 2, 3},
{0, 6, 1, 2}
};
int m = 4, n = 4;
cout << getMaxGold(gold, m, n);
return 0;
}
|
Java
import java.util.Arrays;
class GFG {
static final int MAX = 100 ;
static int getMaxGold( int gold[][],
int m, int n)
{
int goldTable[][] = new int [m][n];
for ( int [] rows:goldTable)
Arrays.fill(rows, 0 );
for ( int col = n- 1 ; col >= 0 ; col--)
{
for ( int row = 0 ; row < m; row++)
{
int right = (col == n- 1 ) ? 0
: goldTable[row][col+ 1 ];
int right_up = (row == 0 ||
col == n- 1 ) ? 0 :
goldTable[row- 1 ][col+ 1 ];
int right_down = (row == m- 1
|| col == n- 1 ) ? 0 :
goldTable[row+ 1 ][col+ 1 ];
goldTable[row][col] = gold[row][col]
+ Math.max(right, Math.max(right_up,
right_down));
}
}
int res = goldTable[ 0 ][ 0 ];
for ( int i = 1 ; i < m; i++)
res = Math.max(res, goldTable[i][ 0 ]);
return res;
}
public static void main(String arg[])
{
int gold[][]= { { 1 , 3 , 1 , 5 },
{ 2 , 2 , 4 , 1 },
{ 5 , 0 , 2 , 3 },
{ 0 , 6 , 1 , 2 } };
int m = 4 , n = 4 ;
System.out.print(getMaxGold(gold, m, n));
}
}
|
Python3
MAX = 100
def getMaxGold(gold, m, n):
goldTable = [[ 0 for i in range (n)]
for j in range (m)]
for col in range (n - 1 , - 1 , - 1 ):
for row in range (m):
if (col = = n - 1 ):
right = 0
else :
right = goldTable[row][col + 1 ]
if (row = = 0 or col = = n - 1 ):
right_up = 0
else :
right_up = goldTable[row - 1 ][col + 1 ]
if (row = = m - 1 or col = = n - 1 ):
right_down = 0
else :
right_down = goldTable[row + 1 ][col + 1 ]
goldTable[row][col] = gold[row][col] + max (right, right_up, right_down)
res = goldTable[ 0 ][ 0 ]
for i in range ( 1 , m):
res = max (res, goldTable[i][ 0 ])
return res
gold = [[ 1 , 3 , 1 , 5 ],
[ 2 , 2 , 4 , 1 ],
[ 5 , 0 , 2 , 3 ],
[ 0 , 6 , 1 , 2 ]]
m = 4
n = 4
print (getMaxGold(gold, m, n))
|
C#
using System;
class GFG
{
static int MAX = 100;
static int getMaxGold( int [,] gold,
int m, int n)
{
int [,] goldTable = new int [m, n];
for ( int i = 0; i < m; i++)
for ( int j = 0; j < n; j++)
goldTable[i, j] = 0;
for ( int col = n - 1; col >= 0; col--)
{
for ( int row = 0; row < m; row++)
{
int right = (col == n - 1) ? 0 :
goldTable[row, col + 1];
int right_up = (row == 0 || col == n - 1)
? 0 : goldTable[row-1,col+1];
int right_down = (row == m - 1 || col == n - 1)
? 0 : goldTable[row + 1, col + 1];
goldTable[row, col] = gold[row, col] +
Math.Max(right, Math.Max(right_up,
right_down));
}
}
int res = goldTable[0, 0];
for ( int i = 1; i < m; i++)
res = Math.Max(res, goldTable[i, 0]);
return res;
}
static void Main()
{
int [,] gold = new int [,]{{1, 3, 1, 5},
{2, 2, 4, 1},
{5, 0, 2, 3},
{0, 6, 1, 2}
};
int m = 4, n = 4;
Console.Write(getMaxGold(gold, m, n));
}
}
|
PHP
<?php
function getMaxGold( $gold , $m , $n )
{
$MAX = 100 ;
$goldTable = array ( array ());
for ( $i = 0; $i < $m ; $i ++)
for ( $j = 0; $j < $n ; $j ++)
$goldTable [ $i ][ $j ] = 0 ;
for ( $col = $n - 1; $col >= 0 ; $col --)
{
for ( $row = 0 ; $row < $m ; $row ++)
{
if ( $col == $n - 1)
$right = 0 ;
else
$right = $goldTable [ $row ][ $col + 1];
if ( $row == 0 or $col == $n - 1)
$right_up = 0 ;
else
$right_up = $goldTable [ $row - 1][ $col + 1];
if ( $row == $m - 1 or $col == $n - 1)
$right_down = 0 ;
else
$right_down = $goldTable [ $row + 1][ $col + 1];
$goldTable [ $row ][ $col ] = $gold [ $row ][ $col ] +
max( $right , $right_up ,
$right_down );
}
}
$res = $goldTable [0][0] ;
for ( $i = 0; $i < $m ; $i ++)
$res = max( $res , $goldTable [ $i ][0]);
return $res ;
}
$gold = array ( array (1, 3, 1, 5),
array (2, 2, 4, 1),
array (5, 0, 2, 3),
array (0, 6, 1, 2));
$m = 4 ;
$n = 4 ;
echo getMaxGold( $gold , $m , $n ) ;
?>
|
Javascript
<script>
let MAX = 100;
function getMaxGold(gold, m, n)
{
let goldTable = new Array(m);
for (let i = 0; i < m; i++)
{
goldTable[i] = new Array(n);
for (let j = 0; j < n; j++)
{
goldTable[i][j] = 0;
}
}
for (let col = n-1; col >= 0; col--)
{
for (let row = 0; row < m; row++)
{
let right = (col == n-1) ? 0
: goldTable[row][col+1];
let right_up = (row == 0 ||
col == n-1) ? 0 :
goldTable[row-1][col+1];
let right_down = (row == m-1
|| col == n-1) ? 0 :
goldTable[row+1][col+1];
goldTable[row][col] = gold[row][col]
+ Math.max(right, Math.max(right_up,
right_down));
}
}
let res = goldTable[0][0];
for (let i = 1; i < m; i++)
res = Math.max(res, goldTable[i][0]);
return res;
}
let gold = [ [1, 3, 1, 5],
[2, 2, 4, 1],
[5, 0, 2, 3],
[0, 6, 1, 2] ];
let m = 4, n = 4;
document.write(getMaxGold(gold, m, n));
</script>
|
Time Complexity: O(m*n)
Auxiliary Space: O(m*n)
Space Complex Solution: In the above-given method we require O(m x n) space. This will not be suitable if the length of strings is greater than 2000 as it can only create 2D array of 2000 x 2000. To fill a row in DP array we require only one row the upper row. For example, if we are filling the i = 10 rows in DP array we require only values of 9th row. So we simply create a DP array of 2 x str1 length. This approach reduces the space complexity. Here is the Python3 implementation of the above-mentioned problem.
C++
#include <bits/stdc++.h>
using namespace std;
int MAX = 100;
int getMaxGold(vector<vector< int >> gold, int m, int n)
{
int goldTable[m][2];
for ( int i = 0; i < m; i++)
{
goldTable[i][0] = 0;
goldTable[i][1] = 0;
}
for ( int col = n - 1; col > -1; col--)
{
for ( int row = 0; row < m; row++)
{
int right, right_up, right_down;
if (col == n-1)
right = 0;
else
right = goldTable[row][(col+1)%2];
if (row == 0 || col == n-1)
right_up = 0;
else
right_up = goldTable[row-1][(col+1)%2];
if (row == m-1 || col == n-1)
right_down = 0;
else
right_down = goldTable[row+1][(col+1)%2];
goldTable[row][col%2] = gold[row][col] + max(right, max(right_up, right_down));
}
}
int res = goldTable[0][0];
for ( int i = 1; i < m; i++)
res = max(res, goldTable[i][0]);
return res;
}
int main()
{
int m = 4;
int n = 4;
vector<vector< int >> gold = {{ 1, 3, 1, 5},
{2, 2, 4, 1},
{5, 0, 2, 3},
{0, 6, 1, 2}};
cout << getMaxGold(gold, m, n) << endl;
}
|
Java
import java.io.*;
class GFG
{
static int MAX = 100 ;
static int getMaxGold( int gold[][], int m, int n)
{
int goldTable[][] = new int [m][ 2 ];
for ( int i = 0 ; i < m; i++)
{
goldTable[i][ 0 ] = 0 ;
goldTable[i][ 1 ] = 0 ;
}
for ( int col = n - 1 ; col > - 1 ; col--)
{
for ( int row = 0 ; row < m; row++)
{
int right, right_up, right_down;
if (col == n- 1 )
right = 0 ;
else
right = goldTable[row][(col+ 1 )% 2 ];
if (row == 0 || col == n- 1 )
right_up = 0 ;
else
right_up = goldTable[row- 1 ][(col+ 1 )% 2 ];
if (row == m- 1 || col == n- 1 )
right_down = 0 ;
else
right_down = goldTable[row+ 1 ][(col+ 1 )% 2 ];
goldTable[row][col% 2 ] = gold[row][col] + Math.max(right, Math.max(right_up, right_down));
}
}
int res = goldTable[ 0 ][ 0 ];
for ( int i = 1 ; i < m; i++)
res = Math.max(res, goldTable[i][ 0 ]);
return res;
}
public static void main(String[] args)
{
int m = 4 ;
int n = 4 ;
int [][] gold = {{ 1 , 3 , 1 , 5 },
{ 2 , 2 , 4 , 1 },
{ 5 , 0 , 2 , 3 },
{ 0 , 6 , 1 , 2 }};
System.out.println(getMaxGold(gold, m, n));
}
}
|
Python3
MAX = 100
def getMaxGold(gold, m, n):
goldTable = [[ 0 for i in range ( 2 )]
for j in range (m)]
for col in range (n - 1 , - 1 , - 1 ):
for row in range (m):
if (col = = n - 1 ):
right = 0
else :
right = goldTable[row][(col + 1 ) % 2 ]
if (row = = 0 or col = = n - 1 ):
right_up = 0
else :
right_up = goldTable[row - 1 ][(col + 1 ) % 2 ]
if (row = = m - 1 or col = = n - 1 ):
right_down = 0
else :
right_down = goldTable[row + 1 ][(col + 1 ) % 2 ]
goldTable[row][col % 2 ] = gold[row][col] + max (right, right_up, right_down)
res = goldTable[ 0 ][ 0 ]
for i in range ( 1 , m):
res = max (res, goldTable[i][ 0 ])
return res
gold = [[ 1 , 3 , 1 , 5 ],
[ 2 , 2 , 4 , 1 ],
[ 5 , 0 , 2 , 3 ],
[ 0 , 6 , 1 , 2 ]]
m = 4
n = 4
print (getMaxGold(gold, m, n))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
int MAX = 100;
static int getMaxGold( int [,] gold, int m, int n)
{
int [,] goldTable = new int [m, 2];
for ( int i = 0; i < m; i++)
{
goldTable[i, 0] = 0;
goldTable[i, 1] = 0;
}
for ( int col = n - 1; col > -1; col--)
{
for ( int row = 0; row < m; row++)
{
int right, right_up, right_down;
if (col == n-1)
right = 0;
else
right = goldTable[row, (col+1)%2];
if (row == 0 || col == n-1)
right_up = 0;
else
right_up = goldTable[row-1, (col+1)%2];
if (row == m-1 || col == n-1)
right_down = 0;
else
right_down = goldTable[row+1, (col+1)%2];
goldTable[row, col%2] = gold[row, col] + Math.Max(right, Math.Max(right_up, right_down));
}
}
int res = goldTable[0, 0];
for ( int i = 1; i < m; i++)
res = Math.Max(res, goldTable[i, 0]);
return res;
}
public static void Main( string [] args)
{
int m = 4;
int n = 4;
int [,] gold = {{ 1, 3, 1, 5},
{2, 2, 4, 1},
{5, 0, 2, 3},
{0, 6, 1, 2}};
Console.WriteLine(getMaxGold(gold, m, n));
}
}
|
Javascript
let MAX = 100
function getMaxGold(gold, m, n)
{
let goldTable = new Array(m);
for ( var i = 0; i < m; i++)
goldTable[i] = new Array(2).fill(0);
for ( var col = n - 1; col > -1; col--)
{
for ( var row = 0; row < m; row++)
{
let right, right_up, right_down;
if (col == n-1)
right = 0;
else
right = goldTable[row][(col+1)%2]
if (row == 0 || col == n-1)
right_up = 0
else
right_up = goldTable[row-1][(col+1)%2]
if (row == m-1 || col == n-1)
right_down = 0
else
right_down = goldTable[row+1][(col+1)%2]
goldTable[row][col%2] = gold[row][col] + Math.max(right, Math.max(right_up, right_down))
}
}
let res = goldTable[0][0]
for ( var i = 1; i < m; i++)
res = Math.max(res, goldTable[i][0])
return res
}
let gold = [[1, 3, 1, 5],
[2, 2, 4, 1],
[5, 0, 2, 3],
[0, 6, 1, 2]]
let m = 4
let n = 4
console.log(getMaxGold(gold, m, n))
|
Time Complexity: O(m*n)
Auxiliary Space: O(m*2)
->Directed Array Approach
Time Complexity – O(m*n)
Space Complexity – O(m*n)
C++
#include <bits/stdc++.h>
using namespace std;
int dx[3] = { -1, 0, 1 };
int dy[3] = { -1, -1, -1 };
bool isValid( int x, int y, int n, int m)
{
if (x >= 0 && x < n && y >= 0 && y < m)
return true ;
return false ;
}
int maxGold( int n, int m, vector<vector< int > > M)
{
int dp[n][m];
for ( int i = 0; i < n; i++)
dp[i][0] = M[i][0];
for ( int j = 1; j < m; j++) {
for ( int i = 0; i < n; i++) {
int mx = INT_MIN;
for ( int k = 0; k < 3; k++) {
int x = i + dx[k];
int y = j + dy[k];
if (isValid(x, y, n, m))
mx = max(mx, dp[x][y] + M[i][j]);
}
dp[i][j] = mx;
}
}
int ans = INT_MIN;
for ( int i = 0; i < n; i++) {
ans = max(ans, dp[i][m - 1]);
}
return ans;
}
int main()
{
int n = 4;
int m = 4;
vector<vector< int > > gold = { { 1, 3, 1, 5 },
{ 2, 2, 4, 1 },
{ 5, 0, 2, 3 },
{ 0, 6, 1, 2 } };
cout << "Max Amount of gold collected = "
<< maxGold(n, m, gold);
return 0;
}
|
Java
import java.util.*;
class GFG {
static int [] dx
= new int [] { - 1 , 0 , 1 };
static int [] dy
= new int [] { - 1 , - 1 , - 1 };
static boolean isValid( int x, int y, int n, int m)
{
if (x >= 0 && x < n && y >= 0 && y < m)
return true ;
return false ;
}
static int maxGold( int n, int m, int [][] M)
{
int [][] dp = new int [n][m];
for ( int i = 0 ; i < n; i++)
dp[i][ 0 ] = M[i][ 0 ];
for ( int j = 1 ; j < m; j++) {
for ( int i = 0 ; i < n; i++) {
int mx = Integer.MIN_VALUE;
for ( int k = 0 ; k < 3 ; k++) {
int x = i + dx[k];
int y = j + dy[k];
if (isValid(x, y, n, m))
mx = Math.max(mx,
dp[x][y] + M[i][j]);
}
dp[i][j] = mx;
}
}
int ans = Integer.MIN_VALUE;
for ( int i = 0 ; i < n; i++) {
ans = Math.max(ans, dp[i][m - 1 ]);
}
return ans;
}
public static void main(String[] args)
{
int n = 4 ;
int m = 4 ;
int [][] gold = new int [][] { { 1 , 3 , 1 , 5 },
{ 2 , 2 , 4 , 1 },
{ 5 , 0 , 2 , 3 },
{ 0 , 6 , 1 , 2 } };
System.out.println( "Max Amount of gold collected = "
+ maxGold(n, m, gold));
}
}
|
Python3
dx = [ - 1 , 0 , 1 ]
dy = [ - 1 , - 1 , - 1 ]
def is_valid(x, y, n, m):
if x > = 0 and x < n and y > = 0 and y < m:
return True
return False
def max_gold(n, m, M):
dp = [[ 0 for j in range (m)] for i in range (n)]
for i in range (n):
dp[i][ 0 ] = M[i][ 0 ]
for j in range ( 1 , m):
for i in range (n):
mx = float ( '-inf' )
for k in range ( 3 ):
x = i + dx[k]
y = j + dy[k]
if is_valid(x, y, n, m):
mx = max (mx, dp[x][y] + M[i][j])
dp[i][j] = mx
ans = float ( '-inf' )
for i in range (n):
ans = max (ans, dp[i][m - 1 ])
return ans
n = 4
m = 4
gold = [
[ 1 , 3 , 1 , 5 ],
[ 2 , 2 , 4 , 1 ],
[ 5 , 0 , 2 , 3 ],
[ 0 , 6 , 1 , 2 ],
]
print ( "Max Amount of gold collected = " , max_gold(n, m, gold))
|
C#
using System;
using System.Collections.Generic;
class GFG {
static int [] dx
= new int [] { -1, 0, 1 };
static int [] dy
= new int [] { -1, -1, -1 };
static bool isValid( int x, int y, int n, int m)
{
if (x >= 0 && x < n && y >= 0 && y < m)
return true ;
return false ;
}
static int maxGold( int n, int m, int [][] M)
{
int [][] dp = new int [n][];
for ( int i = 0; i < n; i++)
dp[i] = new int [m];
for ( int i = 0; i < n; i++)
dp[i][0] = M[i][0];
for ( int j = 1; j < m; j++) {
for ( int i = 0; i < n; i++) {
int mx = Int32.MinValue;
for ( int k = 0; k < 3; k++) {
int x = i + dx[k];
int y = j + dy[k];
if (isValid(x, y, n, m))
mx = Math.Max(mx,
dp[x][y] + M[i][j]);
}
dp[i][j] = mx;
}
}
int ans = Int32.MinValue;
for ( int i = 0; i < n; i++) {
ans = Math.Max(ans, dp[i][m - 1]);
}
return ans;
}
static void Main( string [] args)
{
int n = 4;
int m = 4;
int [][] gold
= new int [][] { new int [] { 1, 3, 1, 5 },
new int [] { 2, 2, 4, 1 },
new int [] { 5, 0, 2, 3 },
new int [] { 0, 6, 1, 2 } };
Console.WriteLine( "Max Amount of gold collected = "
+ maxGold(n, m, gold));
}
}
|
Javascript
const dx = [-1, 0, 1];
const dy = [-1, -1, -1];
function isValid(x, y, n, m) {
if (x >= 0 && x < n && y >= 0 && y < m) {
return true ;
}
return false ;
}
function maxGold(n, m, M) {
let dp = new Array(n);
for (let i = 0; i < dp.length; i++) {
dp[i] = new Array(m);
}
for (let i = 0; i < n; i++) {
dp[i][0] = M[i][0];
}
for (let j = 1; j < m; j++) {
for (let i = 0; i < n; i++) {
let mx = Number.MIN_SAFE_INTEGER;
for (let k = 0; k < 3; k++) {
let x = i + dx[k];
let y = j + dy[k];
if (isValid(x, y, n, m)) {
mx = Math.max(mx, dp[x][y] + M[i][j]);
}
}
dp[i][j] = mx;
}
}
let ans = Number.MIN_SAFE_INTEGER;
for (let i = 0; i < n; i++) {
ans = Math.max(ans, dp[i][m - 1]);
}
return ans;
}
const n = 4;
const m = 4;
const gold = [
[1, 3, 1, 5],
[2, 2, 4, 1],
[5, 0, 2, 3],
[0, 6, 1, 2],
];
console.log( "Max Amount of gold collected = " + maxGold(n, m, gold));
|
OutputMax Amount of gold collected = 16