最大化通过从相邻对中选择至少一个形成的序列的中位数
给定一个包含N 个整数的数组Arr[ ] ,其中1 ≤ N ≤ 10 5 。任务是从数组中选择任意数量的元素,使得:
- 对于每个i ( 0≤ i ≥ N-2 ),必须选择第i个和第(i+1)个元素中的至少一个。
- 从由此形成的数组的子序列中找到最大可能的整数中位数。
例子:
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
方法:该方法基于二进制搜索技术。
- 对所有可能的数字执行二进制搜索,并检查是否可以通过在给定条件下从数组中选择任意数量的元素来获得当前数字作为中位数。
- 在所有可能的值中,最大的一个将是答案。
- 要检查当前值x是否可以是中值,请遵循简单的观察,即如果子序列中有更多数量的元素 ≥ x ,则子序列的中值至少为x 。
- 之后,从原始数组声明一个修改后的数组,这样:
- 对于每个i ( 0 ≤ i ≤ N-1 ) 如果Arr[i] ≥ x ,则modified[i]=1 ,
- 否则修改[i] = -1 。
- 现在,如果有可能在修改后的数组中找到一个子序列(遵循给定条件,必须选择第i个和第(i+1)个元素中的至少一个),则:
- 如果子序列的所有元素之和为正,则当前x可以作为中值获得。
- 修改后的数组中子序列的总和为正表示原始数组中有更多的元素≥ x 。
- 因此, x可以是可能的中位数。
- 要确定是否可以从修改后的数组中获得这样的子序列和,只需从修改后的数组中找到最大可能的子序列和(在给定条件下)并将其与 0 进行比较即可。
- 如果它大于 0,则当前x可以是中值。
- 为了找到最大子序列和,我们将使用代码中解释的动态编程。
下面是上述方法的实现:
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
输出
4
时间复杂度: O(N* log N)
辅助空间: O(N)