Maximum sum from three arrays such that picking elements consecutively from same is not allowed

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 sumint 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 codeint 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 approachclass GFG { static int N = 3; // Function to return the maximum sumstatic 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 codepublic 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 approachvar N = 3;// Function to return the maximum sumfunction 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 codevar 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 arrayvar x = FindMaximumSum(0, 0, a, b, c, n, dp);// Pick element from second arrayvar y = FindMaximumSum(0, 1, a, b, c, n, dp);// Pick element from third arrayvar z = FindMaximumSum(0, 2, a, b, c, n, dp);// Print the maximum of themdocument.write( Math.max(x, Math.max(y, z)));</script> |
PHP
<?php// PHP implementation of the approach$N = 3;// Function to return the maximum sumfunction 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 themprint(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 sumint 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 codeint 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 sysN = 3# Function to return the maximum sumdef 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 codeif __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 Codelet a = [10, 20, 30];let b = [40, 50, 60];let c = [70, 80, 90];let n = a.length;// Call the function and print the resultconsole.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 zambiatek!



