Maximize value of coins when coins from adjacent row and columns cannot be collected
Given a 2D array arr[][] of size N * M, the value in arr[][] represents the value of coins, the task is to maximize the value of collected coins when during collecting the coins from the arr[][], all the coins from the adjacent row (i.e, i – 1 and i + 1) will disappear, and coins at the adjacent column (i.e arr[i][j + 1] and arr[i][j – 1]) will also get disappear.
Examples:
Input: arr[][] = {{2, 7, 6, 5}, {9, 9, 1, 2}, {3, 8, 1, 5}}
Output: 25
Explanation: Collect coin 7, 5, from row 1 and 8 and 5 from row 3.
Input: arr[][] = {{12, 7, 6, 5}, {9, 9, 3, 1}, {9, 8, 1, 2}}
Output: 29
This problem is composed of multiple smaller subproblems.
- First subproblem is that if we somehow know the maximum value of coins collected by each row by following the condition that no two consecutive cell in each of the rows (i.e, arr[i][j + 1] and arr[i][j – 1]) would be collected at the same time. We’ll store this subproblem in some other array and
- Again we have to follow the other constraint of the problem that coins can’t be collected in adjacent row.
And to solve this constraint we’ll again use the similar technique that we used before to find the result.
Follow the steps below to implement the above idea:
- Iterate over each row and call a recursive function (say findMax) to find the maximum coin that can be collected in each row by following the constraint that coins at the adjacent column can’t be collected.
- Store the above result in an array (say dp[]).
- Again call the findMax function for the state stored in the dp[] array, to find the maximum value that can be collected among all rows by considering that coins at adjacent rows can’t be collected.
Below is the implementation of the above approach.
C++
#include <bits/stdc++.h>
using namespace std;
int findMax(vector< int >& arr)
{
int n = arr.size(), result = 0;
vector< int > dp(n);
dp[0] = arr[0];
result = dp[0];
if (n <= 1)
return result;
dp[1] = max(arr[1], arr[0]);
result = max(result, dp[1]);
for ( int i = 2; i < n; i++) {
dp[i] = max(dp[i - 1], arr[i] + dp[i - 2]);
result = max(result, dp[i]);
}
return result;
}
int solve(vector<vector< int > >& matrix)
{
int m = matrix.size();
if (m == 0)
return 0;
vector< int > dp;
for ( int i = 0; i < m; i++) {
int val = findMax(matrix[i]);
dp.push_back(val);
}
return findMax(dp);
}
int main()
{
vector<vector< int > > arr = { { 2, 7, 6, 5 },
{ 9, 9, 1, 2 },
{ 3, 8, 1, 5 } };
int result = solve(arr);
cout << result;
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
static int findMax( int [] arr)
{
int n = arr.length, result = 0 ;
int [] dp = new int [n];
dp[ 0 ] = arr[ 0 ];
result = dp[ 0 ];
if (n <= 1 ) {
return result;
}
dp[ 1 ] = Math.max(arr[ 1 ], arr[ 0 ]);
result = Math.max(result, dp[ 1 ]);
for ( int i = 2 ; i < n; i++) {
dp[i] = Math.max(dp[i - 1 ], arr[i] + dp[i - 2 ]);
result = Math.max(result, dp[i]);
}
return result;
}
static int solve( int [][] matrix)
{
int m = matrix.length;
if (m == 0 ) {
return 0 ;
}
List<Integer> dp = new ArrayList<>();
for ( int i = 0 ; i < m; i++) {
int val = findMax(matrix[i]);
dp.add(val);
}
return findMax(dp.stream()
.mapToInt(Integer::intValue)
.toArray());
}
public static void main(String[] args)
{
int [][] arr = { { 2 , 7 , 6 , 5 },
{ 9 , 9 , 1 , 2 },
{ 3 , 8 , 1 , 5 } };
int result = solve(arr);
System.out.print(result);
}
}
|
Python3
import math
class GFG :
@staticmethod
def findMax( arr) :
n = len (arr)
result = 0
dp = [ 0 ] * (n)
dp[ 0 ] = arr[ 0 ]
result = dp[ 0 ]
if (n < = 1 ) :
return result
dp[ 1 ] = max (arr[ 1 ],arr[ 0 ])
result = max (result,dp[ 1 ])
i = 2
while (i < n) :
dp[i] = max (dp[i - 1 ],arr[i] + dp[i - 2 ])
result = max (result,dp[i])
i + = 1
return result
@staticmethod
def solve( matrix) :
m = len (matrix)
if (m = = 0 ) :
return 0
dp = [ 0 ] * (m)
i = 0
while (i < m) :
val = GFG.findMax(matrix[i])
dp[i] = val
i + = 1
return GFG.findMax(dp)
@staticmethod
def main( args) :
arr = [[ 2 , 7 , 6 , 5 ], [ 9 , 9 , 1 , 2 ], [ 3 , 8 , 1 , 5 ]]
result = GFG.solve(arr)
print (result, end = "")
if __name__ = = "__main__" :
GFG.main([])
|
C#
using System;
using System.Collections;
public class GFG {
static int findMax( int [] arr)
{
int n = arr.Length, result = 0;
int [] dp = new int [n];
dp[0] = arr[0];
result = dp[0];
if (n <= 1) {
return result;
}
dp[1] = Math.Max(arr[1], arr[0]);
result = Math.Max(result, dp[1]);
for ( int i = 2; i < n; i++) {
dp[i] = Math.Max(dp[i - 1], arr[i] + dp[i - 2]);
result = Math.Max(result, dp[i]);
}
return result;
}
static int solve( int [, ] matrix)
{
int m = matrix.GetLength(0);
if (m == 0) {
return 0;
}
int [] dp = new int [m];
for ( int i = 0; i < m; i++) {
int [] temp = new int [(matrix.GetLength(1))];
for ( int j = 0; j < 4; j++) {
temp[j] = matrix[i, j];
}
int val = findMax(temp);
dp[i] = val;
}
return findMax(dp);
}
static public void Main()
{
int [, ] arr = new int [3, 4] { { 2, 7, 6, 5 },
{ 9, 9, 1, 2 },
{ 3, 8, 1, 5 } };
int result = solve(arr);
Console.Write(result);
}
}
|
Javascript
<script>
const findMax = (arr) => {
let n = arr.length, result = 0;
let dp = new Array(n).fill(0);
dp[0] = arr[0];
result = dp[0];
if (n <= 1)
return result;
dp[1] = Math.max(arr[1], arr[0]);
result = Math.max(result, dp[1]);
for (let i = 2; i < n; i++) {
dp[i] = Math.max(dp[i - 1], arr[i] + dp[i - 2]);
result = Math.max(result, dp[i]);
}
return result;
}
const solve = (matrix) => {
let m = matrix.length;
if (m == 0)
return 0;
let dp = [];
for (let i = 0; i < m; i++) {
let val = findMax(matrix[i]);
dp.push(val);
}
return findMax(dp);
}
let arr = [[2, 7, 6, 5],
[9, 9, 1, 2],
[3, 8, 1, 5]];
let result = solve(arr);
document.write(result);
</script>
|
Time Complexity: O(N * M) where N is the number of rows and M is the number of columns
Auxiliary Space: O(max(N, M))
Last Updated :
24 Mar, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...