📌  相关文章
📜  通过从三个给定的数组中选择X个不同索引的元素来最大化总和

📅  最后修改于: 2021-05-19 17:32:14             🧑  作者: Mango

给定三个大小为N的数组A []B []C []以及三个正整数XYZ ,任务是通过选择最多N个数组元素,使得最多X个元素,找到可能的最大和。来自数组A [] ,最多Y个元素来自数组B [] ,最多Z个元素来自数组C [] ,所有元素都来自不同的索引。

例子:

天真的方法:请按照以下步骤解决问题:

  • 遍历所有数组并生成所有可能的组合,以从满足给定条件的三个不同数组中最多选择N个元素:
  • 对于i元素,可以执行以下四个操作:
    • 从数组A []中选择i元素。
    • 从数组A []中选择i元素。
    • 从数组A []中选择i元素。
    • 从任何数组中选择i元素。
  • 因此,解决该问题的递归关系如下:
  • 使用上述递归关系,根据给定条件打印选择N个数组元素的最大和。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
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& A,
             vector& B, vector& 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 A = { 10, 0, 5 };
 
    // Given B[]
    vector B = { 5, 10, 0 };
 
    // Given C[]
    vector 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


C++
// C++ program for the above approach
 
#include 
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& A,
            vector& B, vector& 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 A = { 10, 0, 5 };
 
    // Given B[]
    vector B = { 5, 10, 0 };
 
    // Given C[]
    vector 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


输出:
30

时间复杂度: O(4 N )
辅助空间: O(N)

高效的方法:可以使用备忘录来优化上述方法。请按照以下步骤解决问题:

  • 初始化一个4D数组,例如dp [N] [X] [Y] [Z] ,以存储上述递归关系的重叠子问题。
  • 使用以上重复关系,并使用备注打印dp [N] [X] [Y] [Z]的值

下面是上述方法的实现。

C++

// C++ program for the above approach
 
#include 
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& A,
            vector& B, vector& 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 A = { 10, 0, 5 };
 
    // Given B[]
    vector B = { 5, 10, 0 };
 
    // Given C[]
    vector 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

输出:

30

时间复杂度:O(N * X * Y * Z)

空间复杂度: O(N * X * Y * Z)