# Maximize length of Non-Decreasing Subsequence by reversing at most one Subarray

Given a binary array arr[], the task is to find the maximum possible length of non-decreasing subsequence that can be generated by reversing a subarray at most once.

Examples:

Input: arr[] = {0, 1, 0, 1}
Output:
Explanation:
After reversing the subarray from index [2, 3], the array modifies to {0, 0, 1, 1}.
Hence, the longest non-decreasing subsequence is {0, 0, 1, 1}.

Input: arr[] = {0, 1, 1, 1, 0, 0, 1, 1, 0}
Output:
Explanation:
After reversing the subarray from index [2, 6], the array modifies to {0, 0, 0, 1, 1, 1, 1, 1, 0}.
Hence, the longest non-decreasing subsequence is {0, 0, 0, 1, 1, 1, 1, 1}.

Naive Approach: The simplest approach to solve the problem is to reverse each possible subarray in the given array, and find the longest non-decreasing subsequence possible from the array after reversing the subarray.

Time Complexity: O(N3)
Auxiliary Space: O(N)

Efficient Approach: The idea is to use Dynamic Programming to solve the problem. Follow the steps below:

• Since the array is a binary array the idea is to find the longest subsequence among the subsequences of the forms {0….0}, {0…1…}, {0..1..0…}, 0..1..0..1.
• Initialize a dynamic programming table as dp[][] which stores the following:

dp[i] : Stores the length of the longest subsequence (0..) from a[0 to i].
dp[i] : Stores the length of the longest subsequence (0..1..) from a[0 to i].
dp[i] : Stores the length of the longest subsequence (0..1..0..) from a[0 to i].
dp[i] : Stores the length of the longest subsequence (0..1..0..1..) from a[0 to i].

• Therefore, the answer is the longest subsequence or the maximum of all the 4 given possibilities ( dp[n-1], d[n-1], dp[n-1], dp[n-1] ).

Below is the implementation of the above approach:

## 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[n]; ` `    ``memset``(dp, 0, ``sizeof``(dp * 4 * n)); ` ` `  `    ``if` `(arr == 0) ` `        ``dp = 1; ` `    ``else` `        ``dp = 1; ` ` `  `    ``// Maximum length sub-sequence ` `    ``// of (0..) ` `    ``for``(``int` `i = 1; i < n; i++) ` `    ``{ ` `        ``if` `(arr[i] == 0) ` `            ``dp[i] = dp[i - 1] + 1; ` `        ``else` `            ``dp[i] = dp[i - 1]; ` `    ``} ` ` `  `    ``// Maximum length sub-sequence ` `    ``// of (0..1..) ` `    ``for``(``int` `i = 1; i < n; i++) ` `    ``{ ` `        ``if` `(arr[i] == 1) ` `            ``dp[i] = max(dp[i - 1] + 1,  ` `                           ``dp[i - 1] + 1); ` `        ``else` `            ``dp[i] = dp[i - 1]; ` `    ``} ` ` `  `    ``// Maximum length sub-sequence ` `    ``// of (0..1..0..) ` `    ``for``(``int` `i = 1; i < n; i++) ` `    ``{ ` `        ``if` `(arr[i] == 0) ` `        ``{ ` `            ``dp[i] = max(dp[i - 1] + 1, ` `                           ``max(dp[i - 1] + 1,  ` `                               ``dp[i - 1] + 1)); ` `        ``} ` `        ``else` `            ``dp[i] = dp[i - 1]; ` `    ``} ` ` `  `    ``// Maximum length sub-sequence ` `    ``// of (0..1..0..1..) ` `    ``for``(``int` `i = 1; i < n; i++) ` `    ``{ ` `        ``if` `(arr[i] == 1) ` `        ``{ ` `            ``dp[i] = max(dp[i - 1] + 1, ` `                            ``max(dp[i - 1] + 1,  ` `                                ``max(dp[i - 1] + 1, ` `                                    ``dp[i - 1] + 1))); ` `        ``} ` `        ``else` `            ``dp[i] = dp[i - 1]; ` `    ``} ` ` `  `    ``// Find the max length subsequence ` `    ``int` `ans = max(dp[n - 1], max(dp[n - 1], ` `              ``max(dp[n - 1], dp[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) ` `        ``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   `

Output:

```4
```

Time Complexity: O(N)
Auxiliary Space: O(1)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.

My Personal Notes arrow_drop_up Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.