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++
// 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
// 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
# 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#
// 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 |
Javascript
<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 // 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 :
C++
#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; } |
Java
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 ])); } } |
Python3
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)) |
C#
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)); } } |
Javascript
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)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!