📌  相关文章
📜  通过为子序列中的元素分配交替的正号和负号,可能的最大和

📅  最后修改于: 2021-05-17 17:38:36             🧑  作者: Mango

给定由N个正整数组成的数组arr [] ,任务是从给定数组中找到子序列的最大和,以使子序列中的元素交替分配正号和负号。

例子:

天真的方法:最简单的方法是生成给定数组的所有子序列,然后为每个子序列求和,并在所有子序列的总和中打印最大值。

时间复杂度: O(N * 2 N )
辅助空间: O(1)

高效方法:为了优化上述方法,其思想是使用动态编程。初始化大小为N * 2的辅助空间dp [] []以存储重叠子问题。在每个递归调用中,将arr [i](-1)* arr [i]与相应的标志变量相加,该变量指示当前元素是正还是负。步骤如下:

  • 创建大小为N * 22d dp [] []数组,使用-1初始化该数组。
  • 通过变量标记,该标记表示在下一项中必须选择的元素的符号。例如,在子序列{a,b,c}中,最大子序列可以是(a – b + c)(b – c)c。我不是一次又一次地针对所有重叠子问题重复发生,而是一次存储在dp [] []数组中并使用重复状态。
  • 如果标志为0,则当前元素将被视为正元素;如果标志为1,则当前元素将被视为负元素
  • 将每个结果存储到dp [] []数组中。
  • 完成上述步骤后,将dp [N] [flag]的值打印为最大和。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to find the
// maximum sum subsequence
int findMax(vector& a, int dp[][2],
            int i, int flag)
{
    // Base Case
    if (i == (int)a.size()) {
        return 0;
    }
 
    // If current state is already
    // calculated then use it
    if (dp[i][flag] != -1) {
        return dp[i][flag];
    }
 
    int ans;
 
    // If current element is positive
    if (flag == 0) {
 
        // Update ans and recursively
        // call with update value of flag
        ans = max(findMax(a, dp, i + 1, 0),
                  a[i]
                      + findMax(a, dp,
                                i + 1, 1));
    }
 
    // Else current element is negative
    else {
 
        // Update ans and recursively
        // call with update value of flag
        ans = max(findMax(a, dp, i + 1, 1),
                  -1 * a[i]
                      + findMax(a, dp,
                                i + 1, 0));
    }
 
    // Return maximum sum subsequence
    return dp[i][flag] = ans;
}
 
// Function that finds the maximum
// sum of element of the subsequence
// with alternate +ve and -ve signs
void findMaxSumUtil(vector& arr,
                    int N)
{
    // Create auxiliary array dp[][]
    int dp[N][2];
 
    // Initialize dp[][]
    memset(dp, -1, sizeof dp);
 
    // Function Call
    cout << findMax(arr, dp, 0, 0);
}
 
// Driver Code
int main()
{
    // Given array arr[]
    vector arr = { 1, 2, 3, 4, 1, 2 };
 
    int N = arr.size();
 
    // Function Call
    findMaxSumUtil(arr, N);
 
    return 0;
}


Java
// Java program for the above approach
import java.io.*;
import java.util.Arrays;
 
class GFG{
  
// Function to find the
// maximum sum subsequence
static int findMax(int[] a, int dp[][],
                   int i, int flag)
{
     
    // Base Case
    if (i == (int)a.length)
    {
        return 0;
    }
  
    // If current state is already
    // calculated then use it
    if (dp[i][flag] != -1)
    {
        return dp[i][flag];
    }
  
    int ans;
  
    // If current element is positive
    if (flag == 0)
    {
         
        // Update ans and recursively
        // call with update value of flag
        ans = Math.max(findMax(a, dp, i + 1, 0),
                a[i] + findMax(a, dp, i + 1, 1));
    }
  
    // Else current element is negative
    else
    {
         
        // Update ans and recursively
        // call with update value of flag
        ans = Math.max(findMax(a, dp, i + 1, 1),
           -1 * a[i] + findMax(a, dp, i + 1, 0));
    }
  
    // Return maximum sum subsequence
    return dp[i][flag] = ans;
}
  
// Function that finds the maximum
// sum of element of the subsequence
// with alternate +ve and -ve signs
static void findMaxSumUtil(int[] arr,
                           int N)
{
     
    // Create auxiliary array dp[][]
    int dp[][] = new int[N][2];
  
    // Initialize dp[][]
    for(int i = 0; i < N; i++)
    {
        for(int j = 0; j < 2; j++)
        {
            dp[i][j] = -1;
        }
    }
     
    // Function Call
    System.out.println(findMax(arr, dp, 0, 0));
}
  
// Driver Code
public static void main (String[] args)
{
     
    // Given array arr[]
    int[] arr = { 1, 2, 3, 4, 1, 2 };
  
    int N = arr.length;
  
    // Function call
    findMaxSumUtil(arr, N);
}
}
 
// This code is contributed by sanjoy_62


Python3
# Python3 program for the above approach
 
# Function to find the
# maximum sum subsequence
def findMax(a, dp, i, flag):
     
    # Base Case
    if (i == len(a)):
        return 0
 
    # If current state is already
    # calculated then use it
    if (dp[i][flag] != -1):
        return dp[i][flag]
 
    ans = 0
 
    # If current element is positive
    if (flag == 0):
 
        # Update ans and recursively
        # call with update value of flag
        ans = max(findMax(a, dp, i + 1, 0),
           a[i] + findMax(a, dp, i + 1, 1))
 
    # Else current element is negative
    else:
 
        # Update ans and recursively
        # call with update value of flag
        ans = max(findMax(a, dp, i + 1, 1),
      -1 * a[i] + findMax(a, dp, i + 1, 0))
 
    # Return maximum sum subsequence
    dp[i][flag] = ans
     
    return ans
 
# Function that finds the maximum
# sum of element of the subsequence
# with alternate +ve and -ve signs
def findMaxSumUtil(arr, N):
     
    # Create auxiliary array dp[][]
    dp = [[-1 for i in range(2)]
              for i in range(N)]
 
    # Function call
    print(findMax(arr, dp, 0, 0))
 
# Driver Code
if __name__ == '__main__':
     
    # Given array arr[]
    arr = [ 1, 2, 3, 4, 1, 2 ]
 
    N = len(arr)
 
    # Function call
    findMaxSumUtil(arr, N)
 
# This code is contributed by mohit kumar 29


C#
// C# program for the above approach
using System;
 
class GFG {
  
// Function to find the
// maximum sum subsequence
static int findMax(int[] a, int[,] dp,
                   int i, int flag)
{
     
    // Base Case
    if (i == (int)a.Length)
    {
        return 0;
    }
   
    // If current state is already
    // calculated then use it
    if (dp[i, flag] != -1)
    {
        return dp[i, flag];
    }
   
    int ans;
   
    // If current element is positive
    if (flag == 0)
    {
         
        // Update ans and recursively
        // call with update value of flag
        ans = Math.Max(findMax(a, dp, i + 1, 0),
                a[i] + findMax(a, dp, i + 1, 1));
    }
   
    // Else current element is negative
    else
    {
         
        // Update ans and recursively
        // call with update value of flag
        ans = Math.Max(findMax(a, dp, i + 1, 1),
           -1 * a[i] + findMax(a, dp, i + 1, 0));
    }
   
    // Return maximum sum subsequence
    return dp[i, flag] = ans;
}
   
// Function that finds the maximum
// sum of element of the subsequence
// with alternate +ve and -ve signs
static void findMaxSumUtil(int[] arr,
                           int N)
{
      
    // Create auxiliary array dp[][]
    int[,] dp = new int[N, 2];
   
    // Initialize dp[][]
    for(int i = 0; i < N; i++)
    {
        for(int j = 0; j < 2; j++)
        {
            dp[i, j] = -1;
        }
    }
      
    // Function Call
    Console.WriteLine(findMax(arr, dp, 0, 0));
}
  
// Driver Code
public static void Main()
{
     
    // Given array arr[]
    int[] arr = { 1, 2, 3, 4, 1, 2 };
   
    int N = arr.Length;
   
    // Function call
    findMaxSumUtil(arr, N);
}
}
 
// This code is contributed by code_hunt


输出:
5










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