# Maximize median of sequence formed by choosing at least one from adjacent pairs

Last Updated : 31 Mar, 2022

Given an array Arr[ ] of N integers where 1 â‰¤ N â‰¤ 105. The task is to choose any number of elements from the array such that:

• For each i ( 0â‰¤ i â‰¥ N-2 ), at least one of the ith and (i+1)th elements must be chosen.
• Find the maximum possible median of integers from the subsequence of the array thus formed.

Examples:

Input: N = 6,  Arr[ ] = { 2, 1, 2, 1, 1, 10 }
Output: 2
Explanation : Choosing arr[0], arr[2], arr[4] and arr[5] makes the subsequence as { 2, 2, 1, 10 } giving median as 2 which is maximum possible. Also note that the condition that atleast one of the two consecutive elements must be chosen is satisfied.

Input: N = 7, Arr[ ] = { 3, 1, 4, 1, 5, 9, 2 }
Output: 4

Approach: The approach is based on binary search technique.

• Perform binary search over all possible numbers and check if the current number can be obtained as a median by choosing any number of elements from the array under the given condition.
• Out of all the possible values, the maximum one will be the answer.
• To check if the current value x can be a median or not, follow the simple observation that if there are more number of elements â‰¥ x in the subsequence then the median of the subsequence is at least x.
• After that declare a modified array from the original array such that:
• For each i (0 â‰¤ i â‰¤ N-1 ) if Arr[i] â‰¥ x, then modified[i]=1,
• Else modified[i] = -1.
• Now, if it is possible to find a subsequence in the modified array (following the given condition that at least one of the ith and (i+1)th elements must be chosen) such that:
• If the sum of all elements of the subsequence is positive, then current x can be obtained as a median.
• The sum of the subsequence being positive from the modified array signifies that there are more elements â‰¥ x, in the original array.
• Hence, x can be a possible median.
• To find if such a subsequence sum can be obtained from the modified array, it is sufficient to find the maximum possible subsequence sum(with the given condition) from the modified array and compare it with 0.
• If it is greater than 0, then-current x can be a median.
• To find the maximum subsequence sum, we will use dynamic programming as explained in the code.

Below is the implementation of the above approach:

## C++

 `// C++ code for the above approach:`   `#include ` `using` `namespace` `std;`   `int` `dp[100000 + 5][2];`   `// Function to find maximum subsequence sum` `// from the array under given condition` `// using dynamic programming` `int` `max_subsequence_sum(``int` `arr[], ``int` `n,` `                        ``int` `i, ``int` `last)` `{` `    ``// If we have taken last element already` `    ``// then last = 1 else last = 0` `    ``if` `(i >= n) {` `        ``return` `0;` `    ``}`   `    ``// Already calculated and stored in dp` `    ``// ao return directly` `    ``if` `(dp[i][last] != -1) {` `        ``return` `dp[i][last];` `    ``}`   `    ``if` `(last == 1) {`   `        ``// Last element is taken already` `        ``// so we can either take` `        ``// the current element or leave it` `        ``int` `t1 = arr[i]` `                 ``+ max_subsequence_sum(arr, n,` `                                       ``i + 1, 1);`   `        ``int` `t2 = max_subsequence_sum(arr, n,` `                                     ``i + 1, 0);`   `        ``return` `dp[i][last] = max(t1, t2);` `    ``}` `    ``else` `{`   `        ``// Last element is not taken` `        ``// Hence we need to take` `        ``// the current element` `        ``int` `t = arr[i]` `                ``+ max_subsequence_sum(arr, n,` `                                      ``i + 1, 1);`   `        ``return` `dp[i][last] = t;` `    ``}` `}`   `// Helper function to reset` `// dp values for each call` `int` `helper_max_sub_sum(``int` `arr[], ``int` `n)` `{` `    ``memset``(dp, -1, ``sizeof``(dp));`   `    ``int` `max_sub_sum` `        ``= max_subsequence_sum(arr, n, 0, 1);`   `    ``return` `max_sub_sum;` `}`   `// Function to check if the given median` `// Can be obtained by` `// Choosing any subsequence of the array` `// Under given constraints` `bool` `is_given_median_possible(``int` `arr[],` `                              ``int` `n,` `                              ``int` `median)` `{` `    ``int` `modified[n];`   `    ``// Creating the modified array as explained` `    ``for` `(``int` `i{ 0 }; i < n; i++) {` `        ``if` `(arr[i] >= median) {` `            ``modified[i] = 1;` `        ``}` `        ``else` `{` `            ``modified[i] = -1;` `        ``}` `    ``}` `    ``int` `max_sub_sum` `        ``= helper_max_sub_sum(modified, n);`   `    ``// If max_sub_sum > 0 then current` `    ``// median is possible` `    ``if` `(max_sub_sum > 0) {` `        ``return` `true``;` `    ``}` `    ``return` `false``;` `}`   `// Function to binary search` `// Over all possible values of median` `// To find the max possible median` `int` `binary_search_for_median(``int` `arr[],` `                             ``int` `n)` `{` `    ``int` `ans = 1;` `    ``int` `low = *min_element(arr, arr + n);` `    ``int` `high = *max_element(arr, arr + n);`   `    ``while` `(low <= high) {` `        ``int` `mid = low + (high - low) / 2;`   `        ``if` `(is_given_median_possible(arr,` `                                     ``n, mid)) {` `            ``ans = mid;` `            ``low = mid + 1;` `        ``}` `        ``else` `{` `            ``high = mid - 1;` `        ``}` `    ``}` `    ``return` `ans;` `}`   `// Driver code` `int` `main()` `{` `    ``int` `N = 7;` `    ``int` `Arr[] = { 3, 1, 4, 1, 5, 9, 2 };`   `    ``// Storing the function in ans variable` `    ``int` `ans = binary_search_for_median(Arr, N);` `    ``cout << ans << endl;` `    ``return` `0;` `}`

## Java

 `// Java code for the above approach` `import` `java.util.*;` `class` `GFG ` `{`   `  ``static` `int` `dp[][] = ``new` `int``[``100000` `+ ``5``][``2``];`   `  ``// Function to find maximum subsequence sum` `  ``// from the array under given condition` `  ``// using dynamic programming` `  ``static` `int` `max_subsequence_sum(``int` `arr[], ``int` `n,` `                                 ``int` `i, ``int` `last)` `  ``{` `    ``// If we have taken last element already` `    ``// then last = 1 else last = 0` `    ``if` `(i >= n) {` `      ``return` `0``;` `    ``}`   `    ``// Already calculated and stored in dp` `    ``// ao return directly` `    ``if` `(dp[i][last] != -``1``) {` `      ``return` `dp[i][last];` `    ``}`   `    ``if` `(last == ``1``) {`   `      ``// Last element is taken already` `      ``// so we can either take` `      ``// the current element or leave it` `      ``int` `t1 = arr[i]` `        ``+ max_subsequence_sum(arr, n,` `                              ``i + ``1``, ``1``);`   `      ``int` `t2 = max_subsequence_sum(arr, n,` `                                   ``i + ``1``, ``0``);`   `      ``return` `dp[i][last] = Math.max(t1, t2);` `    ``}` `    ``else` `{`   `      ``// Last element is not taken` `      ``// Hence we need to take` `      ``// the current element` `      ``int` `t = arr[i]` `        ``+ max_subsequence_sum(arr, n,` `                              ``i + ``1``, ``1``);`   `      ``return` `dp[i][last] = t;` `    ``}` `  ``}`   `  ``// Helper function to reset` `  ``// dp values for each call` `  ``static` `int` `helper_max_sub_sum(``int` `arr[], ``int` `n)` `  ``{` `    ``for``(``int` `i=``0``;i= median) {` `        ``modified[i] = ``1``;` `      ``}` `      ``else` `{` `        ``modified[i] = -``1``;` `      ``}` `    ``}` `    ``int` `max_sub_sum` `      ``= helper_max_sub_sum(modified, n);`   `    ``// If max_sub_sum > 0 then current` `    ``// median is possible` `    ``if` `(max_sub_sum > ``0``) {` `      ``return` `true``;` `    ``}` `    ``return` `false``;` `  ``}`   `  ``// Function to binary search` `  ``// Over all possible values of median` `  ``// To find the max possible median` `  ``static` `int` `binary_search_for_median(``int` `arr[],` `                                      ``int` `n)` `  ``{` `    ``int` `ans = ``1``;`   `    ``int` `low = ``99999999``;` `    ``int` `high = -``9999999``;`         `    ``for``(``int` `i=``0``;i

## Python3

 `# Python code for the above approach`   `# Function to find maximum subsequence sum` `# from the array under given condition` `# using dynamic programming` `def` `max_subsequence_sum(arr, n, i, last):` `    ``if` `i >``=` `n:` `        ``return` `0` `    ``if` `dp[i][last] !``=` `-``1``:` `        ``return` `dp[i][last]` `    ``if` `last ``=``=` `1``:` `        ``t1 ``=` `arr[i] ``+` `max_subsequence_sum(arr, n, i``+``1``, ``1``)` `        ``t2 ``=` `max_subsequence_sum(arr, n, i``+``1``, ``0``)` `        ``dp[i][last] ``=` `max``(t1, t2)` `        ``return` `dp[i][last]` `    ``else``:` `        ``t ``=` `arr[i] ``+` `max_subsequence_sum(arr, n, i``+``1``, ``1``)` `        ``dp[i][last] ``=` `t` `        ``return` `dp[i][last]`   `# Helper function to reset` `# dp values for each call` `def` `helper_max_sub_sum(arr, n):` `    ``global` `dp` `    ``dp ``=` `[[``-``1` `for` `i ``in` `range``(``2``)] ``for` `i ``in` `range``(``100000` `+` `5``)]` `    ``max_sub_sum ``=` `max_subsequence_sum(arr, n, ``0``, ``1``)` `    ``return` `max_sub_sum`   `# Function to check if the given median` `# Can be obtained by` `# Choosing any subsequence of the array` `# Under given constraints` `def` `is_given_median_possible(arr, n, median):` `    ``modified ``=` `[[``-``1``, ``1``][arr[i] >``=` `median] ``for` `i ``in` `range``(n)]` `    ``max_sub_sum ``=` `helper_max_sub_sum(modified, n)` `    ``return` `max_sub_sum > ``0`   `# Function to binary search` `# Over all possible values of median` `# To find the max possible median` `def` `binary_search_for_median(arr, n):` `    ``ans ``=` `1` `    ``low ``=` `min``(arr)` `    ``high ``=` `max``(arr)` `    ``while` `(low <``=` `high):` `        ``mid ``=` `int``(low ``+` `(high ``-` `low)``/``2``)` `        ``if` `(is_given_median_possible(arr, n, mid)):` `            ``ans ``=` `mid` `            ``low ``=` `mid ``+` `1` `        ``else``:` `            ``high ``=` `mid ``-` `1`   `    ``return` `ans`   `# Driver Code` `N ``=` `7` `Arr ``=` `[``3``, ``1``, ``4``, ``1``, ``5``, ``9``, ``2``]` `ans ``=` `binary_search_for_median(Arr, N)` `print``(ans)`   `# This code is contributed by phalasi.`

## C#

 `// C# code for the above approach` `using` `System;`   `public` `class` `GFG{`   `  ``static` `int` `[,] dp = ``new` `int``[100000 + 5, 2];`   `  ``// Function to find maximum subsequence sum` `  ``// from the array under given condition` `  ``// using dynamic programming` `  ``static` `int` `max_subsequence_sum(``int``[] arr, ``int` `n,` `                                 ``int` `i, ``int` `last)` `  ``{` `    ``// If we have taken last element already` `    ``// then last = 1 else last = 0` `    ``if` `(i >= n) {` `      ``return` `0;` `    ``}`   `    ``// Already calculated and stored in dp` `    ``// ao return directly` `    ``if` `(dp[i, last] != -1) {` `      ``return` `dp[i, last];` `    ``}`   `    ``if` `(last == 1) {`   `      ``// Last element is taken already` `      ``// so we can either take` `      ``// the current element or leave it` `      ``int` `t1 = arr[i]` `        ``+ max_subsequence_sum(arr, n,` `                              ``i + 1, 1);`   `      ``int` `t2 = max_subsequence_sum(arr, n,` `                                   ``i + 1, 0);`   `      ``return` `dp[i, last] = Math.Max(t1, t2);` `    ``}` `    ``else` `{`   `      ``// Last element is not taken` `      ``// Hence we need to take` `      ``// the current element` `      ``int` `t = arr[i]` `        ``+ max_subsequence_sum(arr, n,` `                              ``i + 1, 1);`   `      ``return` `dp[i, last] = t;` `    ``}` `  ``}`   `  ``// Helper function to reset` `  ``// dp values for each call` `  ``static` `int` `helper_max_sub_sum(``int``[] arr, ``int` `n)` `  ``{` `    ``for``(``int` `i=0;i= median) {` `        ``modified[i] = 1;` `      ``}` `      ``else` `{` `        ``modified[i] = -1;` `      ``}` `    ``}` `    ``int` `max_sub_sum` `      ``= helper_max_sub_sum(modified, n);`   `    ``// If max_sub_sum > 0 then current` `    ``// median is possible` `    ``if` `(max_sub_sum > 0) {` `      ``return` `true``;` `    ``}` `    ``return` `false``;` `  ``}`   `  ``// Function to binary search` `  ``// Over all possible values of median` `  ``// To find the max possible median` `  ``static` `int` `binary_search_for_median(``int``[] arr,` `                                      ``int` `n)` `  ``{` `    ``int` `ans = 1;`   `    ``int` `low = 99999999;` `    ``int` `high = -9999999;`         `    ``for``(``int` `i=0;i

## Javascript

 ``

Output

`4`

Time Complexity: O(N* log N)
Auxiliary Space: O(N)

Previous
Next