给定三个大小为N 的数组A[] 、 B[]和C[]以及三个正整数X 、 Y和Z ,任务是通过选择最多N 个数组元素来找到可能的最大和,使得最多X 个元素来自数组A[] ,至多来自数组B[] 的Y元素,至多Z元素来自数组C[]并且所有元素来自不同的索引。
例子:
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
幼稚的方法:按照以下步骤解决问题:
- 遍历所有数组并生成所有可能的组合,从满足给定条件的三个不同数组中最多选择N 个元素:
- 对于每个第i个元素,可以执行以下四种操作:
- 从数组A[] 中选择第i个元素。
- 从数组A[] 中选择第i个元素。
- 从数组A[] 中选择第i个元素。
- 从任何数组中选择第i个元素。
- 因此,求解该问题的递推关系如下:
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))
- 使用上述递推关系,打印基于给定条件选择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
Javascript
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
Javascript
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
蟒蛇3
# 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
Javascript
输出:
30
时间复杂度:O(N * X * Y * Z)
空间复杂度: O(N * X * Y * Z)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。