Given three arrays A[], B[], and C[] of N integers. We can choose N elements from this array such that for every index i only one element can be chosen from this array i.e. either A[i], B[i], or C[i], and no two consecutive elements can be chosen from the same array. The task is to print the maximum sum of numbers that we can make by choosing elements from these arrays.
Examples:
Input: a[] = {10, 20, 30}, b[] = {40, 50, 60}, c[] = {70, 80, 90}
Output: 210
70 + 50 + 90 = 210Input: a[] = {6, 8, 2, 7, 4, 2, 7}, b[] = {7, 8, 5, 8, 6, 3, 5}, c[] = {8, 3, 2, 6, 8, 4, 1}
Output: 46
Choose elements from C, A, B, A, C, B and A.
Approach: The above problem can be solved using Dynamic Programming. Let dp[i][j] be considered the maximum sum till i if an element from j-th array is chosen. We can select an element from any array for the first index, but later on recursively we can choose an element only from the rest two arrays for the next step. The maximum sum returned by all of the combinations will be our answer. Use memoization to avoid repetitive and multiple same-function calls.
Below is the implementation of the above approach:
// C++ implementation of the approach #include <bits/stdc++.h> using namespace std;
const int N = 3;
// Function to return the maximum sum int FindMaximumSum( int ind, int kon, int a[], int b[],
int c[], int n, int dp[][N])
{ // Base case
if (ind == n)
return 0;
// Already visited
if (dp[ind][kon] != -1)
return dp[ind][kon];
int ans = -1e9 + 5;
// If the element has been taken
// from first array in previous step
if (kon == 0) {
ans = max(ans, b[ind] + FindMaximumSum(ind + 1,
1, a, b,
c, n, dp));
ans = max(ans, c[ind] + FindMaximumSum(ind + 1,
2, a, b,
c, n, dp));
}
// If the element has been taken
// from second array in previous step
else if (kon == 1) {
ans = max(ans, a[ind] + FindMaximumSum(ind + 1,
0, a, b,
c, n, dp));
ans = max(ans, c[ind] + FindMaximumSum(ind + 1,
2, a, b,
c, n, dp));
}
// If the element has been taken
// from third array in previous step
else if (kon == 2) {
ans = max(ans, a[ind] + FindMaximumSum(ind + 1,
1, a, b,
c, n, dp));
ans = max(ans, b[ind] + FindMaximumSum(ind + 1,
0, a, b,
c, n, dp));
}
return dp[ind][kon] = ans;
} // Driver code int main()
{ int a[] = { 6, 8, 2, 7, 4, 2, 7 };
int b[] = { 7, 8, 5, 8, 6, 3, 5 };
int c[] = { 8, 3, 2, 6, 8, 4, 1 };
int n = sizeof (a) / sizeof (a[0]);
int dp[n][N];
memset (dp, -1, sizeof dp);
// Pick element from first array
int x = FindMaximumSum(0, 0, a, b, c, n, dp);
// Pick element from second array
int y = FindMaximumSum(0, 1, a, b, c, n, dp);
// Pick element from third array
int z = FindMaximumSum(0, 2, a, b, c, n, dp);
// Print the maximum of them
cout << max(x, max(y, z));
return 0;
} |
// Java program for the above approach class GFG {
static int N = 3 ;
// Function to return the maximum sum static int FindMaximumSum( int ind, int kon, int a[],
int b[], int c[], int n, int dp[][])
{ // Base case
if (ind == n)
return 0 ;
// Already visited
if (dp[ind][kon] != - 1 )
return dp[ind][kon];
int ans = ( int ) (-1e9 + 5 );
// If the element has been taken
// from first array in previous step
if (kon == 0 ) {
ans = Math.max(ans, b[ind] +
FindMaximumSum(ind + 1 ,
1 , a, b,c, n, dp));
ans = Math.max(ans, c[ind] +
FindMaximumSum(ind + 1 ,
2 , a, b,c, n, dp));
}
// If the element has been taken
// from second array in previous step
else if (kon == 1 ) {
ans = Math.max(ans, a[ind] +
FindMaximumSum(ind + 1 ,
0 , a, b, c, n, dp));
ans = Math.max(ans, c[ind] +
FindMaximumSum(ind + 1 ,
2 , a, b, c, n, dp));
}
// If the element has been taken
// from third array in previous step
else if (kon == 2 ) {
ans = Math.max(ans, a[ind] +
FindMaximumSum(ind + 1 ,
1 , a, b, c, n, dp));
ans = Math.max(ans, b[ind] +
FindMaximumSum(ind + 1 ,
0 , a, b, c, n, dp));
}
return dp[ind][kon] = ans;
} // Driver code public static void main(String[] args) {
int a[] = { 6 , 8 , 2 , 7 , 4 , 2 , 7 };
int b[] = { 7 , 8 , 5 , 8 , 6 , 3 , 5 };
int c[] = { 8 , 3 , 2 , 6 , 8 , 4 , 1 };
int n = a.length;
int dp[][] = new int [n][N];
for ( int i = 0 ; i < n; i++) {
for ( int j = 0 ; j < N; j++) {
dp[i][j] =- 1 ;
}
}
// Pick element from first array
int x = FindMaximumSum( 0 , 0 , a, b, c, n, dp);
// Pick element from second array
int y = FindMaximumSum( 0 , 1 , a, b, c, n, dp);
// Pick element from third array
int z = FindMaximumSum( 0 , 2 , a, b, c, n, dp);
// Print the maximum of them
System.out.println(Math.max(x, Math.max(y, z)));
}
} // This code has been contributed // by 29AjayKumar |
# Python3 implementation of the approach # Function to return the maximum sum def FindMaximumSum(ind, kon, a, b, c, n, dp):
# Base case
if ind = = n:
return 0
# Already visited
if dp[ind][kon] ! = - 1 :
return dp[ind][kon]
ans = - 10 * * 9 + 5
# If the element has been taken
# from first array in previous step
if kon = = 0 :
ans = max (ans, b[ind] +
FindMaximumSum(ind + 1 , 1 ,
a, b, c, n, dp))
ans = max (ans, c[ind] +
FindMaximumSum(ind + 1 , 2 ,
a, b, c, n, dp))
# If the element has been taken
# from second array in previous step
elif kon = = 1 :
ans = max (ans, a[ind] +
FindMaximumSum(ind + 1 , 0 ,
a, b, c, n, dp))
ans = max (ans, c[ind] +
FindMaximumSum(ind + 1 , 2 ,
a, b, c, n, dp))
# If the element has been taken
# from third array in previous step
elif kon = = 2 :
ans = max (ans, a[ind] +
FindMaximumSum(ind + 1 , 1 ,
a, b, c, n, dp))
ans = max (ans, b[ind] +
FindMaximumSum(ind + 1 , 0 ,
a, b, c, n, dp))
dp[ind][kon] = ans
return ans
# Driver code if __name__ = = "__main__" :
N = 3
a = [ 6 , 8 , 2 , 7 , 4 , 2 , 7 ]
b = [ 7 , 8 , 5 , 8 , 6 , 3 , 5 ]
c = [ 8 , 3 , 2 , 6 , 8 , 4 , 1 ]
n = len (a)
dp = [[ - 1 for i in range (N)]
for j in range (n)]
# Pick element from first array
x = FindMaximumSum( 0 , 0 , a, b, c, n, dp)
# Pick element from second array
y = FindMaximumSum( 0 , 1 , a, b, c, n, dp)
# Pick element from third array
z = FindMaximumSum( 0 , 2 , a, b, c, n, dp)
# Print the maximum of them
print ( max (x, y, z))
# This code is contributed # by Rituraj Jain |
// C# program for the above approach using System;
class GFG
{ static int N = 3;
// Function to return the maximum sum
static int FindMaximumSum( int ind, int kon, int []a,
int []b, int []c, int n, int [,]dp)
{
// Base case
if (ind == n)
return 0;
// Already visited
if (dp[ind,kon] != -1)
return dp[ind,kon];
int ans = ( int ) (-1e9 + 5);
// If the element has been taken
// from first array in previous step
if (kon == 0)
{
ans = Math.Max(ans, b[ind] +
FindMaximumSum(ind + 1,
1, a, b,c, n, dp));
ans = Math.Max(ans, c[ind] +
FindMaximumSum(ind + 1,
2, a, b,c, n, dp));
}
// If the element has been taken
// from second array in previous step
else if (kon == 1)
{
ans = Math.Max(ans, a[ind] +
FindMaximumSum(ind + 1,
0, a, b, c, n, dp));
ans = Math.Max(ans, c[ind] +
FindMaximumSum(ind + 1,
2, a, b, c, n, dp));
}
// If the element has been taken
// from third array in previous step
else if (kon == 2)
{
ans = Math.Max(ans, a[ind] +
FindMaximumSum(ind + 1,
1, a, b, c, n, dp));
ans = Math.Max(ans, b[ind] +
FindMaximumSum(ind + 1,
0, a, b, c, n, dp));
}
return dp[ind,kon] = ans;
}
// Driver code
public static void Main()
{
int []a = { 6, 8, 2, 7, 4, 2, 7 };
int []b = { 7, 8, 5, 8, 6, 3, 5 };
int []c = { 8, 3, 2, 6, 8, 4, 1 };
int n = a.Length;
int [,]dp = new int [n,N];
for ( int i = 0; i < n; i++)
{
for ( int j = 0; j < N; j++)
{
dp[i,j] =- 1;
}
}
// Pick element from first array
int x = FindMaximumSum(0, 0, a, b, c, n, dp);
// Pick element from second array
int y = FindMaximumSum(0, 1, a, b, c, n, dp);
// Pick element from third array
int z = FindMaximumSum(0, 2, a, b, c, n, dp);
// Print the maximum of them
Console.WriteLine(Math.Max(x, Math.Max(y, z)));
}
} // This code has been contributed by Ryuga |
<script> // JavaScript implementation of the approach var N = 3;
// Function to return the maximum sum function FindMaximumSum(ind, kon, a, b, c, n, dp)
{ // Base case
if (ind == n)
return 0;
// Already visited
if (dp[ind][kon] != -1)
return dp[ind][kon];
var ans = -1000000005;
// If the element has been taken
// from first array in previous step
if (kon == 0) {
ans = Math.max(ans, b[ind] + FindMaximumSum(ind + 1,
1, a, b,
c, n, dp));
ans = Math.max(ans, c[ind] + FindMaximumSum(ind + 1,
2, a, b,
c, n, dp));
}
// If the element has been taken
// from second array in previous step
else if (kon == 1) {
ans = Math.max(ans, a[ind] + FindMaximumSum(ind + 1,
0, a, b,
c, n, dp));
ans = Math.max(ans, c[ind] + FindMaximumSum(ind + 1,
2, a, b,
c, n, dp));
}
// If the element has been taken
// from third array in previous step
else if (kon == 2) {
ans = Math.max(ans, a[ind] + FindMaximumSum(ind + 1,
1, a, b,
c, n, dp));
ans = Math.max(ans, b[ind] + FindMaximumSum(ind + 1,
0, a, b,
c, n, dp));
}
return dp[ind][kon] = ans;
} // Driver code var a = [ 6, 8, 2, 7, 4, 2, 7 ];
var b = [ 7, 8, 5, 8, 6, 3, 5 ];
var c = [ 8, 3, 2, 6, 8, 4, 1 ];
var n = a.length;
var dp = Array.from(Array(n), ()=> Array(n).fill(-1));
// Pick element from first array var x = FindMaximumSum(0, 0, a, b, c, n, dp);
// Pick element from second array var y = FindMaximumSum(0, 1, a, b, c, n, dp);
// Pick element from third array var z = FindMaximumSum(0, 2, a, b, c, n, dp);
// Print the maximum of them document.write( Math.max(x, Math.max(y, z))); </script> |
<?php // PHP implementation of the approach $N = 3;
// Function to return the maximum sum function FindMaximumSum( $ind , $kon , $a ,
$b , $c , $n , $dp )
{ global $N ;
// Base case
if ( $ind == $n )
return 0;
// Already visited
if ( $dp [ $ind ][ $kon ] != -1)
return $dp [ $ind ][ $kon ];
$ans = -1e9 + 5;
// If the element has been taken
// from first array in previous step
if ( $kon == 0)
{
$ans = max( $ans , $b [ $ind ] +
FindMaximumSum( $ind + 1, 1, $a ,
$b , $c , $n , $dp ));
$ans = max( $ans , $c [ $ind ] +
FindMaximumSum( $ind + 1, 2, $a ,
$b , $c , $n , $dp ));
}
// If the element has been taken
// from second array in previous step
else if ( $kon == 1)
{
$ans = max( $ans , $a [ $ind ] +
FindMaximumSum( $ind + 1, 0,
$a , $b , $c , $n , $dp ));
$ans = max( $ans , $c [ $ind ] +
FindMaximumSum( $ind + 1, 2,
$a , $b , $c , $n , $dp ));
}
// If the element has been taken
// from third array in previous step
else if ( $kon == 2)
{
$ans = max( $ans , $a [ $ind ] +
FindMaximumSum( $ind + 1, 1,
$a , $b , $c , $n , $dp ));
$ans = max( $ans , $b [ $ind ] +
FindMaximumSum( $ind + 1, 0,
$a , $b , $c , $n , $dp ));
}
return $dp [ $ind ][ $kon ] = $ans ;
} // Driver code $a = array ( 6, 8, 2, 7, 4, 2, 7 );
$b = array ( 7, 8, 5, 8, 6, 3, 5 );
$c = array ( 8, 3, 2, 6, 8, 4, 1 );
$n = count ( $a );
$dp = array_fill (0, $n ,
array_fill (0, $N , -1));
// Pick element from first array $x = FindMaximumSum(0, 0, $a , $b ,
$c , $n , $dp );
// Pick element from second array $y = FindMaximumSum(0, 1, $a , $b ,
$c , $n , $dp );
// Pick element from third array $z = FindMaximumSum(0, 2, $a , $b ,
$c , $n , $dp );
// Print the maximum of them print (max( $x , max( $y , $z )));
// This code is contributed by mits ?> |
45
Time Complexity: O(N), as we are using recursion with memorization we will avoid the redundant function calls. Where N is the number of elements in the array.
Auxiliary Space: O(N), as we use extra space for the dp matrix. Where N is the number of elements in the array.
Efficient Approach: Using the DP Tabulation method ( Iterative approach )
The approach to solving this problem is the same but the DP tabulation(bottom-up) method is better than Dp + memoization(top-down) because the memoization method needs extra stack space for recursion calls.
Steps:
- Create a DP to store the solution of the subproblems and initialize it with 0.
- Initialize the DP with base cases
- Now Iterate over subproblems to get the value of the current problem from the previous computation of subproblems stored in DP
- At last, find the maximum value in DP and return an answer.
Implementation :
#include <bits/stdc++.h> using namespace std;
const int N = 3;
// Function to return the maximum sum int FindMaximumSum( int a[], int b[], int c[], int n)
{ int dp[n][N];
memset (dp, 0, sizeof dp);
// Set the first row of dp table
dp[0][0] = a[0];
dp[0][1] = b[0];
dp[0][2] = c[0];
// Iterate over remaining elements
for ( int i = 1; i < n; i++) {
dp[i][0] = max(dp[i-1][1], dp[i-1][2]) + a[i];
dp[i][1] = max(dp[i-1][0], dp[i-1][2]) + b[i];
dp[i][2] = max(dp[i-1][0], dp[i-1][1]) + c[i];
}
// Return the maximum sum
return max(dp[n-1][0], max(dp[n-1][1], dp[n-1][2]));
} // Driver code int main()
{ int a[] = {10, 20, 30}, b[] = {40, 50, 60}, c[] = {70, 80, 90} ;
int n = sizeof (a) / sizeof (a[0]);
// Call the function
cout << FindMaximumSum(a, b, c, n);
return 0;
} |
import java.util.Arrays;
public class Main {
// Driver Code
public static void main(String[] args)
{
int [] a = { 10 , 20 , 30 };
int [] b = { 40 , 50 , 60 };
int [] c = { 70 , 80 , 90 };
int n = a.length;
// Call the function and
// print the result
System.out.println(FindMaximumSum(a, b, c, n));
}
// Function to return the maximum sum
public static int FindMaximumSum( int [] a, int [] b,
int [] c, int n)
{
int [][] dp = new int [n][ 3 ];
for ( int [] row : dp) {
Arrays.fill(row, 0 );
}
// Set the first row of dp table
dp[ 0 ][ 0 ] = a[ 0 ];
dp[ 0 ][ 1 ] = b[ 0 ];
dp[ 0 ][ 2 ] = c[ 0 ];
// Iterate over remaining elements
for ( int i = 1 ; i < n; i++) {
dp[i][ 0 ] = Math.max(dp[i - 1 ][ 1 ], dp[i - 1 ][ 2 ])
+ a[i];
dp[i][ 1 ] = Math.max(dp[i - 1 ][ 0 ], dp[i - 1 ][ 2 ])
+ b[i];
dp[i][ 2 ] = Math.max(dp[i - 1 ][ 0 ], dp[i - 1 ][ 1 ])
+ c[i];
}
// Return the maximum sum
return Math.max(
dp[n - 1 ][ 0 ],
Math.max(dp[n - 1 ][ 1 ], dp[n - 1 ][ 2 ]));
}
} |
import sys
N = 3
# Function to return the maximum sum def find_maximum_sum(a, b, c, n):
dp = [[ 0 for i in range (N)] for j in range (n)]
# Set the first row of dp table
dp[ 0 ][ 0 ] = a[ 0 ]
dp[ 0 ][ 1 ] = b[ 0 ]
dp[ 0 ][ 2 ] = c[ 0 ]
# Iterate over remaining elements
for i in range ( 1 , n):
dp[i][ 0 ] = max (dp[i - 1 ][ 1 ], dp[i - 1 ][ 2 ]) + a[i]
dp[i][ 1 ] = max (dp[i - 1 ][ 0 ], dp[i - 1 ][ 2 ]) + b[i]
dp[i][ 2 ] = max (dp[i - 1 ][ 0 ], dp[i - 1 ][ 1 ]) + c[i]
# Return the maximum sum
return max (dp[n - 1 ][ 0 ], max (dp[n - 1 ][ 1 ], dp[n - 1 ][ 2 ]))
# Driver code if __name__ = = "__main__" :
a = [ 10 , 20 , 30 ]
b = [ 40 , 50 , 60 ]
c = [ 70 , 80 , 90 ]
n = len (a)
# Call the function
print (find_maximum_sum(a, b, c, n))
|
using System;
public class Program {
public static int FindMaximumSum( int [] a, int [] b, int [] c, int n)
{ int [,] dp = new int [n, 3];
dp[0, 0] = a[0]; dp[0, 1] = b[0]; dp[0, 2] = c[0]; for ( int i = 1; i < n; i++) {
dp[i, 0] = Math.Max(dp[i-1, 1], dp[i-1, 2]) + a[i];
dp[i, 1] = Math.Max(dp[i-1, 0], dp[i-1, 2]) + b[i];
dp[i, 2] = Math.Max(dp[i-1, 0], dp[i-1, 1]) + c[i];
}
return Math.Max(dp[n-1, 0], Math.Max(dp[n-1, 1], dp[n-1, 2]));
} public static void Main()
{ int [] a = {10, 20, 30};
int [] b = {40, 50, 60};
int [] c = {70, 80, 90};
int n = a.Length;
Console.WriteLine(FindMaximumSum(a, b, c, n));
} } |
function FindMaximumSum(a, b, c, n) {
let dp = [];
for (let i = 0; i < n; i++) {
dp.push([0, 0, 0]);
}
// Set the first row of dp table
dp[0][0] = a[0];
dp[0][1] = b[0];
dp[0][2] = c[0];
// Iterate over remaining elements
for (let i = 1; i < n; i++) {
dp[i][0] = Math.max(dp[i - 1][1], dp[i - 1][2]) + a[i];
dp[i][1] = Math.max(dp[i - 1][0], dp[i - 1][2]) + b[i];
dp[i][2] = Math.max(dp[i - 1][0], dp[i - 1][1]) + c[i];
}
// Return the maximum sum
return Math.max(dp[n - 1][0], Math.max(dp[n - 1][1], dp[n - 1][2]));
} // Driver Code let a = [10, 20, 30]; let b = [40, 50, 60]; let c = [70, 80, 90]; let n = a.length; // Call the function and print the result console.log(FindMaximumSum(a, b, c, n)); |
210
Time Complexity: O(N)
Auxiliary Space: O(N)