给定三个大小为N的数组A [] , B []和C []以及三个正整数X , Y和Z ,任务是通过选择最多N个数组元素,使得最多X个元素,找到可能的最大和。来自数组A [] ,最多Y个元素来自数组B [] ,最多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
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)