Thursday, July 4, 2024
HomeData ModellingDynamic ProgrammingMaximum sum from three arrays such that picking elements consecutively from same...

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


Output

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));


Output

210

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

Feeling lost in the world of random DSA topics, wasting time without progress? It’s time for a change! Join our DSA course, where we’ll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!

Dominic Rubhabha Wardslaus
Dominic Rubhabha Wardslaushttps://neveropen.dev
infosec,malicious & dos attacks generator, boot rom exploit philanthropist , wild hacker , game developer,
RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments