给定N个整数的三个数组A [] , B []和C [] 。我们可以从这些数组中选择N个元素,以便对于每个索引i,只能从这些数组中选择一个元素,即A [i] , B [i]或C [i],并且不能从同一数组中选择两个连续的元素大批。任务是打印出我们可以通过从这些数组中选择元素而得出的最大数字总和。
例子:
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.
方法:可以使用动态编程解决以上问题。如果从第j个数组中选择元素,则将dp [i] [j]视为直到i的最大和。我们可以从任何数组中选择一个元素作为第一个索引,但随后递归地,我们只能从其余两个数组中选择一个元素用于下一步。所有组合返回的最大和将是我们的答案。使用备忘录可避免重复和多个相同的函数调用。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
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
PHP
输出:
45
时间复杂度: O(N)
辅助空间: O(N)