// 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