Skip to content
Related Articles

Related Articles

Maximize sum by selecting X different-indexed elements from three given arrays
  • Last Updated : 04 Feb, 2021
GeeksforGeeks - Summer Carnival Banner

Given three arrays A[], B[] and C[] of size N and three positive integers X, Y, and Z, the task is to find the maximum sum possible by selecting at most N array elements such that at most X elements are from the array A[], at most Y elements from the array B[], at most Z elements are from the array C[] and all elements are from different indices.

Examples:

Input: A[] = {10, 0, 5}, B[] = {5, 10, 0}, C[] = {0, 5, 10}, X = 1, Y = 1, Z = 1
Output: 30 
Explanation: 
Selecting A[0], B[1], C[2] makes the sum = A[0] + B[1] + C[2] = 30, which is the maximum possible sum after satisfying the given conditions. 
Therefore, the required output is 30. 

Input: A[] = {0}, B[] = {0}, C[] = {0}, X = 1, Y = 1, Z = 1
Output: 0

Naive approach: Follow the steps below to solve the problem:



  • Traverse all the arrays and generate all the possible combinations to select at most N elements from the three different arrays that satisfies the given condition:
  • For every ith element, the following four operations can be performed: 
    • Select ith element from the array, A[].
    • Select ith element from the array, A[].
    • Select ith element from the array, A[].
    • Select ith element from any of the arrays.
  • Therefore, the recurrence relation to solve the problem is as follows:

FindMaxS(X, Y, Z, i) = max(A[i] + FindMaxS(X – 1, Y, Z, i – 1), B[i] + FindMaxS(X, Y – 1, Z, i – 1), C[i] + FindMaxS(X, Y, Z – 1, i – 1), FindMaxS(X, Y, Z, i – 1))

  • Using the above recurrence relation, print the maximum sum of selecting N array elements based on the given conditions.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find maximum sum of at most N with
// different index array elements such that at most X
// are from A[], Y are from B[] and Z are from C[]
int FindMaxS(int X, int Y, int Z, int n, vector<int>& A,
             vector<int>& B, vector<int>& C)
{
 
    // Base Cases
    if (X < 0 or Y < 0 or Z < 0)
        return INT_MIN;
    if (n < 0)
        return 0;
 
    // Selecting i-th element from A[]
    int ch = A[n] + FindMaxS(X - 1, Y, Z,
                             n - 1, A, B, C);
 
    // Selecting i-th element from B[]
    int ca = B[n] + FindMaxS(X, Y - 1, Z, n - 1,
                             A, B, C);
 
    // Selecting i-th element from C[]
    int co = C[n] + FindMaxS(X, Y, Z - 1, n - 1,
                             A, B, C);
 
    // i-th elements not selected from
    // any of the arrays
    int no = FindMaxS(X, Y, Z, n - 1, A, B, C);
 
    // Select the maximum sum from all
    // the possible calls
    int maximum = max(ch, max(ca, max(co, no)));
 
    return maximum;
}
 
// Driver Code
int main()
{
 
    // Given X, Y and Z
 
    int X = 1;
    int Y = 1;
    int Z = 1;
 
    // Given A[]
    vector<int> A = { 10, 0, 5 };
 
    // Given B[]
    vector<int> B = { 5, 10, 0 };
 
    // Given C[]
    vector<int> C = { 0, 5, 10 };
 
    // Given Size
    int n = B.size();
 
    // Function Call
    cout << FindMaxS(X, Y, Z, n - 1, A, B, C);
}

Java




// Java program for the above approach
class GFG{
 
// Function to find maximum sum of at most N with
// different index array elements such that at most X
// are from A[], Y are from B[] and Z are from C[]
static int FindMaxS(int X, int Y, int Z, int n,
                    int A[], int B[], int C[])
{
     
    // Base Cases
    if (X < 0 || Y < 0 || Z < 0)
        return Integer.MIN_VALUE;
    if (n < 0)
        return 0;
 
    // Selecting i-th element from A[]
    int ch = A[n] + FindMaxS(X - 1, Y, Z,
                             n - 1, A, B, C);
 
    // Selecting i-th element from B[]
    int ca = B[n] + FindMaxS(X, Y - 1, Z, n - 1,
                             A, B, C);
 
    // Selecting i-th element from C[]
    int co = C[n] + FindMaxS(X, Y, Z - 1, n - 1,
                             A, B, C);
 
    // i-th elements not selected from
    // any of the arrays
    int no = FindMaxS(X, Y, Z, n - 1, A, B, C);
 
    // Select the maximum sum from all
    // the possible calls
    int maximum = Math.max(ch, Math.max(
        ca, Math.max(co, no)));
 
    return maximum;
}
 
// Driver Code
public static void main (String[] args)
{
     
    // Given X, Y and Z
    int X = 1;
    int Y = 1;
    int Z = 1;
 
    // Given A[]
    int A[] = { 10, 0, 5 };
 
    // Given B[]
    int B[] = { 5, 10, 0 };
 
    // Given C[]
    int C[] = { 0, 5, 10 };
 
    // Given Size
    int n = B.length;
 
    // Function Call
    System.out.println(FindMaxS(X, Y, Z, n - 1, A, B, C));
}
}
 
// This code is contributed by AnkThon

Python3




# Python3 program for the above approach
 
# Function to find maximum sum of at most N with
# different index array elements such that at most X
# are from A[], Y are from B[] and Z are from C[]
def FindMaxS(X, Y, Z, n):
 
    global A, B, C
    if (X < 0 or Y < 0 or Z < 0):
        return -10**9
    if (n < 0):
        return 0
 
    # Selecting i-th element from A[]
    ch = A[n] + FindMaxS(X - 1, Y, Z,n - 1)
 
    # Selecting i-th element from B[]
    ca = B[n] + FindMaxS(X, Y - 1, Z, n - 1)
 
    # Selecting i-th element from C[]
    co = C[n] + FindMaxS(X, Y, Z - 1, n - 1)
 
    # i-th elements not selected from
    # any of the arrays
    no = FindMaxS(X, Y, Z, n - 1)
 
    # Select the maximum sum from all
    # the possible calls
    maximum = max(ch, max(ca, max(co, no)))
    return maximum
 
# Driver Code
if __name__ == '__main__':
 
    # Given X, Y and Z
    X = 1
    Y = 1
    Z = 1
 
    # Given A[]
    A = [10, 0, 5]
 
    # Given B[]
    B = [5, 10, 0]
 
    # Given C[]
    C = [0, 5, 10]
 
    # Given Size
    n = len(B)
 
    # Function Call
    print (FindMaxS(X, Y, Z, n - 1))
 
    # This code is contributed by mohit kumar 29

C#




// C# program for the above approach
using System;
class GFG
{
 
// Function to find maximum sum of at most N with
// different index array elements such that at most X
// are from []A, Y are from []B and Z are from C[]
static int FindMaxS(int X, int Y, int Z, int n,
                    int []A, int []B, int []C)
{
     
    // Base Cases
    if (X < 0 || Y < 0 || Z < 0)
        return int.MinValue;
    if (n < 0)
        return 0;
 
    // Selecting i-th element from []A
    int ch = A[n] + FindMaxS(X - 1, Y, Z,
                             n - 1, A, B, C);
 
    // Selecting i-th element from []B
    int ca = B[n] + FindMaxS(X, Y - 1, Z, n - 1,
                             A, B, C);
 
    // Selecting i-th element from C[]
    int co = C[n] + FindMaxS(X, Y, Z - 1, n - 1,
                             A, B, C);
 
    // i-th elements not selected from
    // any of the arrays
    int no = FindMaxS(X, Y, Z, n - 1, A, B, C);
 
    // Select the maximum sum from all
    // the possible calls
    int maximum = Math.Max(ch, Math.Max(
        ca, Math.Max(co, no)));
    return maximum;
}
 
// Driver Code
public static void Main(String[] args)
{
     
    // Given X, Y and Z
    int X = 1;
    int Y = 1;
    int Z = 1;
 
    // Given []A
    int []A = { 10, 0, 5 };
 
    // Given []B
    int []B = { 5, 10, 0 };
 
    // Given C[]
    int []C = { 0, 5, 10 };
 
    // Given Size
    int n = B.Length;
 
    // Function Call
    Console.WriteLine(FindMaxS(X, Y, Z, n - 1, A, B, C));
}
}
 
// This code is contributed by shikhasingrajput
Output: 
30

 

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

Efficient Approach: The above approach can be optimized using memoization. Follow the steps below to solve the problem:

  • Initialize a 4D array, say dp[N][X][Y][Z], to store the overlapping subproblems of the above recurrence relation.
  • Use the above recurrence relation and print the value of dp[N][X][Y][Z] using memoization.

Below is the implementation of above approach.

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Store overlapping subproblems
// of the recurrence relation
int dp[50][50][50][50];
 
// Function to find maximum sum of at most N with
// different index array elements such that at most X
// are from A[], Y are from B[] and Z are from C[]
int FindMaxS(int X, int Y, int Z, int n, vector<int>& A,
            vector<int>& B, vector<int>& C)
{
 
    // Base Cases
    if (X < 0 or Y < 0 or Z < 0)
        return INT_MIN;
    if (n < 0)
        return 0;
 
    // If the subproblem already computed
    if (dp[n][X][Y][Z] != -1) {
 
        return dp[n][X][Y][Z];
    }
 
    // Selecting i-th element from A[]
    int ch = A[n] + FindMaxS(X - 1, Y, Z,
                             n - 1, A, B, C);
 
    // Selecting i-th element from B[]
    int ca = B[n] + FindMaxS(X, Y - 1, Z, n - 1,
                             A, B, C);
 
    // Selecting i-th element from C[]
    int co = C[n] + FindMaxS(X, Y, Z - 1, n - 1,
                             A, B, C);
 
    // i-th elements not selected from
    // any of the arrays
    int no = FindMaxS(X, Y, Z, n - 1, A, B, C);
 
    // Select the maximum sum from all
    // the possible calls
    int maximum = max(ch, max(ca, max(co, no)));
    return dp[n][X][Y][Z] = maximum;
}
 
// Driver Code
int main()
{
 
    // Given X, Y and Z
    int X = 1;
    int Y = 1;
    int Z = 1;
 
    // Given A[]
    vector<int> A = { 10, 0, 5 };
 
    // Given B[]
    vector<int> B = { 5, 10, 0 };
 
    // Given C[]
    vector<int> C = { 0, 5, 10 };
 
    // Given Size
    int n = B.size();
    memset(dp, -1, sizeof(dp));
 
    // Function Call
    cout << FindMaxS(X, Y, Z, n - 1, A, B, C);
}

Java




// Java program for the above approach
import java.util.*;
 
class GFG{
 
// Store overlapping subproblems
// of the recurrence relation
static int [][][][]dp = new int[50][50][50][50];
 
// Function to find maximum sum of at most N with
// different index array elements such that at most X
// are from A[], Y are from B[] and Z are from C[]
static int FindMaxS(int X, int Y, int Z, int n,
                    int []A, int []B, int []C)
{
     
    // Base Cases
    if (X < 0 || Y < 0 || Z < 0)
        return Integer.MIN_VALUE;
    if (n < 0)
        return 0;
 
    // If the subproblem already computed
    if (dp[n][X][Y][Z] != -1)
    {
        return dp[n][X][Y][Z];
    }
 
    // Selecting i-th element from A[]
    int ch = A[n] + FindMaxS(X - 1, Y, Z,
                             n - 1, A, B, C);
 
    // Selecting i-th element from B[]
    int ca = B[n] + FindMaxS(X, Y - 1, Z, n - 1,
                             A, B, C);
 
    // Selecting i-th element from C[]
    int co = C[n] + FindMaxS(X, Y, Z - 1, n - 1,
                             A, B, C);
 
    // i-th elements not selected from
    // any of the arrays
    int no = FindMaxS(X, Y, Z, n - 1, A, B, C);
 
    // Select the maximum sum from all
    // the possible calls
    int maximum = Math.max(
        ch, Math.max(ca, Math.max(co, no)));
    return dp[n][X][Y][Z] = maximum;
}
 
// Driver Code
public static void main(String[] args)
{
 
    // Given X, Y and Z
    int X = 1;
    int Y = 1;
    int Z = 1;
 
    // Given A[]
    int []A = { 10, 0, 5 };
 
    // Given B[]
    int []B = { 5, 10, 0 };
 
    // Given C[]
    int []C = { 0, 5, 10 };
 
    // Given Size
    int n = B.length;
    for(int i = 0; i < 50; i++)
         for(int j = 0; j < 50; j++)
             for(int k = 0; k < 50; k++)
                 for(int l = 0; l < 50; l++)
                     dp[i][j][k][l] = -1;
 
    // Function Call
    System.out.print(FindMaxS(X, Y, Z, n - 1,
                              A, B, C));
}
}
 
// This code is contributed by 29AjayKumar

Python3




# Python3 program for the above approach
import sys
 
# Store overlapping subproblems
# of the recurrence relation
dp =  [[[[-1 for i in range(50)] for j in range(50)] for k in range(50)] for l in range(50)]
 
# Function to find maximum sum of at most N with
# different index array elements such that at most X
# are from A[], Y are from B[] and Z are from C[]
def FindMaxS(X, Y, Z, n, A, B, C):
   
    # Base Cases
    if (X < 0 or Y < 0 or Z < 0):
        return -sys.maxsize - 1
    if (n < 0):
        return 0
 
    # If the subproblem already computed
    if (dp[n][X][Y][Z] != -1):
        return dp[n][X][Y][Z]
 
    # Selecting i-th element from A[]
    ch = A[n] + FindMaxS(X - 1, Y, Z, n - 1, A, B, C)
 
    # Selecting i-th element from B[]
    ca = B[n] + FindMaxS(X, Y - 1, Z, n - 1, A, B, C)
 
    # Selecting i-th element from C[]
    co = C[n] + FindMaxS(X, Y, Z - 1, n - 1,A, B, C)
 
    # i-th elements not selected from
    # any of the arrays
    no = FindMaxS(X, Y, Z, n - 1, A, B, C)
 
    # Select the maximum sum from all
    # the possible calls
    maximum = max(ch, max(ca, max(co, no)))
    dp[n][X][Y][Z] = maximum
    return dp[n][X][Y][Z]
 
# Driver Code
if __name__ == '__main__':
   
    # Given X, Y and Z
    X = 1
    Y = 1
    Z = 1
 
    # Given A[]
    A =  [10, 0, 5]
 
    # Given B[]
    B =  [5, 10, 0]
 
    # Given C[]
    C =  [0, 5, 10]
 
    # Given Size
    n = len(B)
     
    # Function Call
    print(FindMaxS(X, Y, Z, n - 1, A, B, C))
 
   # This code is contributed by bgangwar59

C#




// C# program for the above approach
using System;
 
class GFG{
 
// Store overlapping subproblems
// of the recurrence relation
static int[,,,] dp = new int[50, 50, 50, 50];
 
// Function to find maximum sum of at most N with
// different index array elements such that at most X
// are from A[], Y are from B[] and Z are from C[]
static int FindMaxS(int X, int Y, int Z, int n,
                    int[] A, int[] B, int[] C)
{
     
    // Base Cases
    if (X < 0 || Y < 0 || Z < 0)
        return Int32.MinValue;
    if (n < 0)
        return 0;
 
    // If the subproblem already computed
    if (dp[n, X, Y, Z] != -1)
    {
        return dp[n, X, Y, Z];
    }
 
    // Selecting i-th element from A[]
    int ch = A[n] + FindMaxS(X - 1, Y, Z,
                             n - 1, A, B, C);
 
    // Selecting i-th element from B[]
    int ca = B[n] + FindMaxS(X, Y - 1, Z,
                                n - 1, A, B, C);
 
    // Selecting i-th element from C[]
    int co = C[n] + FindMaxS(X, Y, Z - 1, n - 1,
                             A, B, C);
 
    // i-th elements not selected from
    // any of the arrays
    int no = FindMaxS(X, Y, Z, n - 1, A, B, C);
 
    // Select the maximum sum from all
    // the possible calls
    int maximum = Math.Max(
        ch, Math.Max(ca, Math.Max(co, no)));
    return dp[n, X, Y, Z] = maximum;
}
 
// Driver Code
public static void Main(string[] args)
{
     
    // Given X, Y and Z
    int X = 1;
    int Y = 1;
    int Z = 1;
 
    // Given A[]
    int[] A = { 10, 0, 5 };
 
    // Given B[]
    int[] B = { 5, 10, 0 };
 
    // Given C[]
    int[] C = { 0, 5, 10 };
 
    // Given Size
    int n = B.Length;
    for(int i = 0; i < 50; i++)
        for(int j = 0; j < 50; j++)
            for(int k = 0; k < 50; k++)
                for(int l = 0; l < 50; l++)
                    dp[i, j, k, l] = -1;
 
    // Function Call
    Console.Write(FindMaxS(X, Y, Z, n - 1, A, B, C));
}
}
 
// This code is contributed by chitranayal

Output:

30

Time Complexity: O(N * X * Y * Z)

Space Complexity: O(N * X * Y * Z)

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.

My Personal Notes arrow_drop_up
Recommended Articles
Page :