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

• Difficulty Level : Hard
• Last Updated : 01 Jun, 2021

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][0] : Stores the length of the longest subsequence (0..) from a[0 to i].
dp[i][1] : Stores the length of the longest subsequence (0..1..) from a[0 to i].
dp[i][2] : Stores the length of the longest subsequence (0..1..0..) from a[0 to i].
dp[i][3] : 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][0], d[n-1][1], dp[n-1][2], dp[n-1][3] ).

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

 ``

Output:

`4`

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

My Personal Notes arrow_drop_up