📌  相关文章
📜  来自三个数组的最大和,不允许从该数组连续拾取元素

📅  最后修改于: 2021-04-23 05:25:56             🧑  作者: Mango

给定N个整数的三个数组A []B []C [] 。我们可以从这些数组中选择N个元素,以便对于每个索引i,只能从这些数组中选择一个元素,即A [i]B [i]C [i],并且不能从同一数组中选择两个连续的元素大批。我们的任务是打印出我们可以通过从这些数组中选择元素而得出的最大数字总和。

例子:

方法:可以使用动态编程解决以上问题。如果从第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)