题目链接
题意:
给定一个大小为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;
}