📜  由不同奇偶校验的连续元素组成的最大和子序列

📅  最后修改于: 2021-09-22 10:23:47             🧑  作者: Mango

给定一个由N 个整数组成的数组arr[] ,任务是找到一个非空的最大和 子序列,使得每对连续项具有不同的奇偶校验(偶数奇数)。

例子:

朴素方法:解决给定问题的最简单方法是生成数组的所有可能子序列,并找到具有不同奇偶校验的所有相邻元素的子序列的最大和。

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

高效方法:上述方法也可以通过使用动态规划进行优化,因为它具有重叠的子问题和最优子结构。子问题可以使用记忆存储在dp[][]表中,其中dp[i][prev]存储从第i 个位置到数组末尾的最大和,当所选的前一个数字的奇偶校验为‘prev’ 时。每个状态有两种情况:

  • 如果奇偶校验与前一个元素不同,则包括当前元素。
  • 不要包含当前元素。

维护一个布尔变量is_selected以确保至少 从子序列中的数组中选择一个数字,然后在每次递归调用中返回两种情况中的最大值。请按照以下步骤解决问题:

  • 通过执行以下步骤定义递归函数maxSum(i, prev, is_selected)
    • 检查基本情况,如果i的值等于N ,则返回0 ,或者如果i的值等于N – 1并且is_selectedfalse ,则返回arr[i]
    • 如果已经计算了状态dp[i][prev]的结果,则返回此状态dp[i][prev]
    • 如果当前元素的奇偶校验与prev不同,则选择当前元素作为子集的一部分,并为索引(i + 1)处的元素递归调用maxSum函数。
    • 跳过当前子集的当前元素并递归调用索引(i + 1)maxSum函数。
    • 从当前递归调用中返回两种情况的最大值。
  • 完成上述步骤后,打印maxSum(0)的值作为结果。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
int dp[100][3];
 
// Function to find the maximum sum of
// subsequence with consecutive terms
// having different parity
int maxSum(int* arr, int i, int n,
           int prev, bool is_selected)
{
    // Base Case
    if (i == n) {
        return 0;
    }
 
    // Store the parity of number at
    // the ith position
    int cur = abs(arr[i]) % 2;
 
    // If the dp state has already been
    // calculated, return it
    if (dp[i][prev] != -1) {
        return dp[i][prev];
    }
 
    // If the array is traversed and
    // no element has been selected yet
    // then select the current element
    if (i == n - 1 && is_selected == 0)
        return dp[i][prev] = arr[i];
 
    // If the parity of the current and
    // previously selected element are
    // different, then select the
    // current element
    if (cur != prev) {
        dp[i][prev] = arr[i]
                      + maxSum(arr, i + 1,
                               n, cur, 1);
    }
 
    // Skip the current element and move
    // to the next element
    dp[i][prev]
        = max(dp[i][prev],
              maxSum(arr, i + 1, n,
                     prev, is_selected));
 
    // Return the result
    return dp[i][prev];
}
 
// Function to calculate the maximum sum
// subsequence with consecutive terms
// having different parity
void maxSumUtil(int arr[], int n)
{
 
    // Initialize the dp[] array with -1
    memset(dp, -1, sizeof(dp));
 
    // Initially the prev value is set to
    // say 2, as the first element can
    // anyways be selected
    cout << maxSum(arr, 0, n, 2, 0);
}
 
// Driver Code
int main()
{
    int arr[] = { 1, 2, 6, 8, -5, 10 };
    int N = sizeof(arr) / sizeof(arr[0]);
    maxSumUtil(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 of
// subsequence with consecutive terms
// having different parity
static int maxSum(int[] arr, int i, int n, int prev,
                  boolean is_selected, int[][] dp)
{
     
    // Base Case
    if (i == n)
    {
        return 0;
    }
 
    // Store the parity of number at
    // the ith position
    int cur = Math.abs(arr[i]) % 2;
 
    // If the dp state has already been
    // calculated, return it
    if (dp[i][prev] != -1)
    {
        return dp[i][prev];
    }
 
    // If the array is traversed and
    // no element has been selected yet
    // then select the current element
    if (i == n - 1 && is_selected == false)
        return dp[i][prev] = arr[i];
 
    // If the parity of the current and
    // previously selected element are
    // different, then select the
    // current element
    if (cur != prev)
    {
        dp[i][prev] = arr[i] + maxSum(arr, i + 1, n,
                                      cur, true, dp);
    }
 
    // Skip the current element and move
    // to the next element
    dp[i][prev] = Math.max(dp[i][prev], maxSum(
        arr, i + 1, n, prev, is_selected, dp));
                                                
    // Return the result
    return dp[i][prev];
}
 
// Function to calculate the maximum sum
// subsequence with consecutive terms
// having different parity
static void maxSumUtil(int arr[], int n)
{
      int [][]dp = new int[100][3];
       
    // Initialize the dp[] array with -1
    for(int[] arr1 : dp)
        Arrays.fill(arr1, -1);
 
    // Initially the prev value is set to
    // say 2, as the first element can
    // anyways be selected
    System.out.print(maxSum(arr, 0, n, 2, false, dp));
}
 
// Driver Code
public static void main(String[] args)
{
    int arr[] = { 1, 2, 6, 8, -5, 10 };
    int N = arr.length;
     
    maxSumUtil(arr, N);
}
}
 
// This code is contributed by shreyasshetty788


Python3
# Python3 code for the above approach
 
# Function to calculate the maximum sum
# subsequence with consecutive terms
# having different parity
def maxSum(arr, i, n, prev, is_selected, dp):
     
    # Base Case
    if(i == n):
        return 0
 
    # Store the parity of number at
    # the ith position
    cur = abs(arr[i]) % 2
 
    # If the dp state has already been
    # calculated, return it
    if (dp[i][prev] != -1):
        return dp[i][prev]
 
    # If the array is traversed and
    # no element has been selected yet
    # then select the current element
    if (i == n - 1 and is_selected == 0):
        dp[i][prev] = arr[i]
        return dp[i][prev]
 
    # If the parity of the current and
    # previously selected element are
    # different, then select the
    # current element
    if (cur != prev):
        dp[i][prev] = arr[i] + maxSum(arr, i + 1,
                                      n, cur, 1, dp)
 
    # Skip the current element and move
    # to the next element
    dp[i][prev] = max(dp[i][prev], maxSum(
        arr, i + 1, n, prev, is_selected, dp))
 
    # Return the result
    return dp[i][prev]
 
# Function to calculate the maximum sum
# subsequence with consecutive terms
# having different parity
def maxSumUtil(arr, n):
     
    dp = [[-1 for i in range(3)]
              for j in range(100)]
               
    print(maxSum(arr, 0, n, 2, 0, dp))
 
# Driver Code
if __name__ == '__main__':
     
    arr = [ 1, 2, 6, 8, -5, 10 ]
    N = len(arr)
     
    maxSumUtil(arr, N)
     
# This code is contributed by shreyasshetty788


C#
// C# program for the above approach
using System;
 
class GFG{
     
// Function to find the maximum sum of
// subsequence with consecutive terms
// having different parity
static int maxSum(int []arr, int i, int n, int prev,
                  bool is_selected, int [,]dp)
{
     
    // Base Case
    if (i == n)
    {
        return 0;
    }
 
    // Store the parity of number at
    // the ith position
    int cur = Math.Abs(arr[i]) % 2;
 
    // If the dp state has already been
    // calculated, return it
    if (dp[i, prev] != -1)
    {
        return dp[i, prev];
    }
 
    // If the array is traversed and
    // no element has been selected yet
    // then select the current element
    if (i == n - 1 && is_selected == false)
        return dp[i, prev] = arr[i];
 
    // If the parity of the current and
    // previously selected element are
    // different, then select the
    // current element
    if (cur != prev)
    {
        dp[i, prev] = arr[i] + maxSum(arr, i + 1, n,
                                      cur, true, dp);
    }
 
    // Skip the current element and move
    // to the next element
    dp[i, prev] = Math.Max(dp[i, prev], maxSum(
        arr, i + 1, n, prev, is_selected, dp));
 
    // Return the result
    return dp[i, prev];
}
 
// Function to calculate the maximum sum
// subsequence with consecutive terms
// having different parity
static void maxSumUtil(int []arr, int n)
{
    int [,]dp = new int[100, 3];
     
    // Initialize the dp[] array with -1
    for(int i = 0; i < 100; ++i)
    {
        for(int j = 0; j < 3; ++j)
        {
            dp[i, j] = -1;
        }
    }
 
    // Initially the prev value is set to
    // say 2, as the first element can
    // anyways be selected
    Console.Write(maxSum(arr, 0, n, 2, false, dp));
}
 
// Driver code
public static void Main(String []args)
{
    int []arr = { 1, 2, 6, 8, -5, 10 };
    int N = arr.Length;
     
    maxSumUtil(arr, N);
}
}
 
// This code is contributed by shreyasshetty788


Javascript


输出:
14

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

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程