📌  相关文章
📜  通过反转最多一个子阵列来最大化非递减子序列的长度

📅  最后修改于: 2021-09-07 02:04:48             🧑  作者: Mango

给定一个二元数组arr[] ,任务是找到最多可以通过反转子数组一次生成的非递减子序列的最大可能长度。

例子:

朴素的方法:解决问题的最简单的方法是将给定数组中的每个可能的子数组反转,并在反转子数组后从数组中找到可能的最长非递减子序列。

时间复杂度: O(N 3 )
辅助空间: O(N)
高效的方法:思想是使用动态规划来解决问题。请按照以下步骤操作:

  • 由于数组是一个二元数组,所以思想是在{0….0} , {0…1…} , {0..1..0…}, 0..1形式的子序列中找到最长的子序列..0..1 .
  • 将动态规划表初始化为dp[][] ,其中存储以下内容:
  • 因此,答案是最长的子序列或所有 4 种给定可能性中的最大值( dp[n-1][0], d[n-1][1], dp[n-1][2], dp[ n-1][3] )

下面是上述方法的实现:

C++
// C++ program to implement
// the above approach
#include
using namespace std;
 
// Function to find the maximum length
// non decreasing subarray by reversing
// at most one subarray
void main_fun(int arr[], int n)
{
 
    // dp[i][j] be the longest
    // subsequence of a[0...i]
    // with first j parts
    int dp[4][n];
    memset(dp, 0, sizeof(dp[0][0] * 4 * n));
 
    if (arr[0] == 0)
        dp[0][0] = 1;
    else
        dp[1][0] = 1;
 
    // Maximum length sub-sequence
    // of (0..)
    for(int i = 1; i < n; i++)
    {
        if (arr[i] == 0)
            dp[0][i] = dp[0][i - 1] + 1;
        else
            dp[0][i] = dp[0][i - 1];
    }
 
    // Maximum length sub-sequence
    // of (0..1..)
    for(int i = 1; i < n; i++)
    {
        if (arr[i] == 1)
            dp[1][i] = max(dp[1][i - 1] + 1,
                           dp[0][i - 1] + 1);
        else
            dp[1][i] = dp[1][i - 1];
    }
 
    // Maximum length sub-sequence
    // of (0..1..0..)
    for(int i = 1; i < n; i++)
    {
        if (arr[i] == 0)
        {
            dp[2][i] = max(dp[2][i - 1] + 1,
                           max(dp[1][i - 1] + 1,
                               dp[0][i - 1] + 1));
        }
        else
            dp[2][i] = dp[2][i - 1];
    }
 
    // Maximum length sub-sequence
    // of (0..1..0..1..)
    for(int i = 1; i < n; i++)
    {
        if (arr[i] == 1)
        {
            dp[3][i] = max(dp[3][i - 1] + 1,
                            max(dp[2][i - 1] + 1,
                                max(dp[1][i - 1] + 1,
                                    dp[0][i - 1] + 1)));
        }
        else
            dp[3][i] = dp[3][i - 1];
    }
 
    // Find the max length subsequence
    int ans = max(dp[2][n - 1], max(dp[1][n - 1],
              max(dp[0][n - 1], dp[3][n - 1])));
 
    // Print the answer
    cout << (ans);
}
 
// Driver Code
int main()
{
    int n = 4;
    int arr[] = {0, 1, 0, 1};
     
    main_fun(arr, n);
    return 0;
}
 
// This code is contributed by chitranayal


Java
// Java program to implement
// the above approach
import java.util.*;
 
class GFG{
 
// Function to find the maximum length
// non decreasing subarray by reversing
// at most one subarray
static void main_fun(int arr[], int n)
{
     
    // dp[i][j] be the longest
    // subsequence of a[0...i]
    // with first j parts
    int[][] dp = new int[4][n];
 
    if (arr[0] == 0)
        dp[0][0] = 1;
    else
        dp[1][0] = 1;
 
    // Maximum length sub-sequence
    // of (0..)
    for(int i = 1; i < n; i++)
    {
        if (arr[i] == 0)
            dp[0][i] = dp[0][i - 1] + 1;
        else
            dp[0][i] = dp[0][i - 1];
    }
 
    // Maximum length sub-sequence
    // of (0..1..)
    for(int i = 1; i < n; i++)
    {
        if (arr[i] == 1)
            dp[1][i] = Math.max(dp[1][i - 1] + 1,
                                dp[0][i - 1] + 1);
        else
            dp[1][i] = dp[1][i - 1];
    }
 
    // Maximum length sub-sequence
    // of (0..1..0..)
    for(int i = 1; i < n; i++)
    {
        if (arr[i] == 0)
        {
            dp[2][i] = Math.max(dp[2][i - 1] + 1,
                       Math.max(dp[1][i - 1] + 1,
                                dp[0][i - 1] + 1));
        }
        else
            dp[2][i] = dp[2][i - 1];
    }
 
    // Maximum length sub-sequence
    // of (0..1..0..1..)
    for(int i = 1; i < n; i++)
    {
        if (arr[i] == 1)
        {
            dp[3][i] = Math.max(dp[3][i - 1] + 1,
                       Math.max(dp[2][i - 1] + 1,
                       Math.max(dp[1][i - 1] + 1,
                                dp[0][i - 1] + 1)));
        }
        else
            dp[3][i] = dp[3][i - 1];
    }
 
    // Find the max length subsequence
    int ans = Math.max(dp[2][n - 1],
              Math.max(dp[1][n - 1],
              Math.max(dp[0][n - 1],
                       dp[3][n - 1])));
 
    // Print the answer
    System.out.print(ans);
}
 
// Driver code
public static void main (String[] args)
{
    int n = 4;
    int arr[] = { 0, 1, 0, 1 };
     
    main_fun(arr, n);
}
}
 
// This code is contributed by offbeat


Python3
# Python3 program to implement
# the above approach
import sys
 
# Function to find the maximum length
# non decreasing subarray by reversing
# at most one subarray
def main(arr, n):
 
    # dp[i][j] be the longest
    # subsequence of a[0...i]
    # with first j parts
    dp = [[0 for x in range(n)] for y in range(4)]
 
    if arr[0] == 0:
        dp[0][0] = 1
    else:
        dp[1][0] = 1
 
    # Maximum length sub-sequence
    # of (0..)
    for i in range(1, n):
        if arr[i] == 0:
            dp[0][i] = dp[0][i-1] + 1
        else:
            dp[0][i] = dp[0][i-1]
 
    # Maximum length sub-sequence
    # of (0..1..)
    for i in range(1, n):
        if arr[i] == 1:
            dp[1][i] = max(dp[1][i-1] + 1, dp[0][i-1] + 1)
        else:
            dp[1][i] = dp[1][i-1]
 
    # Maximum length sub-sequence
    # of (0..1..0..)
    for i in range(1, n):
        if arr[i] == 0:
            dp[2][i] = max([dp[2][i-1] + 1,
                            dp[1][i-1] + 1,
                            dp[0][i-1] + 1])
        else:
            dp[2][i] = dp[2][i-1]
 
    # Maximum length sub-sequence
    # of (0..1..0..1..)
    for i in range(1, n):
        if arr[i] == 1:
            dp[3][i] = max([dp[3][i-1] + 1,
                            dp[2][i-1] + 1,
                            dp[1][i-1] + 1,
                            dp[0][i-1] + 1])
        else:
            dp[3][i] = dp[3][i-1]
 
    # Find the max length subsequence
    ans = max([dp[2][n-1], dp[1][n-1],
            dp[0][n-1], dp[3][n-1]])
 
    # Print the answer
    print(ans)
 
 
# Driver Code
if __name__ == "__main__":
    n = 4
    arr = [0, 1, 0, 1]
    main(arr, n)


C#
// C# program to implement
// the above approach
using System;
 
class GFG{
 
// Function to find the maximum length
// non decreasing subarray by reversing
// at most one subarray
static void main_fun(int []arr, int n)
{
     
    // dp[i,j] be the longest
    // subsequence of a[0...i]
    // with first j parts
    int[,] dp = new int[4, n];
 
    if (arr[0] == 0)
        dp[0, 0] = 1;
    else
        dp[1, 0] = 1;
 
    // Maximum length sub-sequence
    // of (0..)
    for(int i = 1; i < n; i++)
    {
        if (arr[i] == 0)
            dp[0, i] = dp[0, i - 1] + 1;
        else
            dp[0, i] = dp[0, i - 1];
    }
 
    // Maximum length sub-sequence
    // of (0..1..)
    for(int i = 1; i < n; i++)
    {
        if (arr[i] == 1)
            dp[1, i] = Math.Max(dp[1, i - 1] + 1,
                                dp[0, i - 1] + 1);
        else
            dp[1, i] = dp[1, i - 1];
    }
 
    // Maximum length sub-sequence
    // of (0..1..0..)
    for(int i = 1; i < n; i++)
    {
        if (arr[i] == 0)
        {
            dp[2, i] = Math.Max(dp[2, i - 1] + 1,
                       Math.Max(dp[1, i - 1] + 1,
                                dp[0, i - 1] + 1));
        }
        else
            dp[2, i] = dp[2, i - 1];
    }
 
    // Maximum length sub-sequence
    // of (0..1..0..1..)
    for(int i = 1; i < n; i++)
    {
        if (arr[i] == 1)
        {
            dp[3, i] = Math.Max(dp[3, i - 1] + 1,
                       Math.Max(dp[2, i - 1] + 1,
                       Math.Max(dp[1, i - 1] + 1,
                                dp[0, i - 1] + 1)));
        }
        else
            dp[3, i] = dp[3, i - 1];
    }
 
    // Find the max length subsequence
    int ans = Math.Max(dp[2, n - 1],
              Math.Max(dp[1, n - 1],
              Math.Max(dp[0, n - 1],
                       dp[3, n - 1])));
 
    // Print the answer
    Console.Write(ans);
}
 
// Driver code
public static void Main(String[] args)
{
    int n = 4;
    int []arr = { 0, 1, 0, 1 };
     
    main_fun(arr, n);
}
}
 
// This code is contributed by Amit Katiyar


Javascript


输出:
4

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

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live