Odd-Even Subsequence
题目链接
题意:
给定一个大小为n的数组a,要求找到一个长度为k的子序列s,使得这个子序列的成本最小。这里提到的“成本”定义为:对于子序列s中奇数位置上的所有元素取最大值,以及对于偶数位置上的所有元素取最大值,然后取这两个最大值中的较小者作为该子序列的成本。
思路:
二分答案,考虑如何check mid,check时考虑贪心,考虑奇数时最大值小于等于mid,如果不行再考虑偶数。时间复杂度O(nlogn),具体实现见代码。
点击查看代码
// #pragma GCC optimize("O3")
// #pragma G++ optimize("O3")
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
#define ll long long
#define itn int
const int N = 2e5+5;
int arr[N];
int n,k;
bool ok(int x){
itn g=0;
int ji,ou,jiend,ouend;
if(k&1){
ji=k/2+1,ou=ji-1,jiend=n,ouend=n-1;
}else{
ou=ji=k/2,jiend=n-1,ouend=n;
}
for(int i=1;i<=jiend;){
if(arr[i]<=x){
g++;
i+=2;
if(g==ji){
return 1; //奇数满足则返回true
}
}else{
i++;
}
}
g=0;
for(int i=2;i<=ouend;){
if(arr[i]<=x){
g++;
i+=2;
if(g==ou){
return 1; //偶数满足返回true
}
}else{
i++;
}
}
return 0; //奇偶都不满足,返回false
}
void solve(){
cin>>n>>k;
int zuida=0;
int zuixiao=1e9+4;
for(int i=1;i<=n;++i){
cin>>arr[i];
zuida=max(zuida,arr[i]);
zuixiao=min(zuixiao,arr[i]);
}
int l=zuixiao,r=zuida;
while(r-l>5){
int mid=(l+r)>>1;
if(ok(mid)){
r=mid;
}else{
l=mid+1;
}
}
for(int i=l;i<=r;++i){
if(ok(i)){
cout<<i<<endl;
return ;
}
}
}
signed main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int _=1;
// cin>>_;
while(_--)
solve();
return 0;
}

浙公网安备 33010602011771号