Given three arrays A[], B[] and C[] of N integers. We can choose N elements from these array such that for every index i only one element can be chosen from these 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 element from j-th array is choosen. We can select 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 repetative 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 |
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)
Auxiliary Space: O(N)
Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.