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 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 = 210

Input: 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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right


PHP

Output:

45

Time Complexity: O(N)
Auxiliary Space: O(N)



My Personal Notes arrow_drop_up

Striver(underscore)79 at Codechef and codeforces D

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.