D. Odd-Even Subsequence
题目大意:在a数组中 保留k个数字,如何代价最小的多少。
代价的算法 具体看题意:就是k数组中 min{max{奇数下标},max{偶数下标}}
解题思路:贪心加二分,二分全部的答案(即代价),然后检查能不能达到这个代价。
检查的思路: 我们只要 奇数下标或者偶数下标中 所以的数都小于mid值就能达到这个代价。
所以我们分为奇数下标和偶数下标来检查。
贪心策略:如果我们在检查奇数下标的时候,那么我们从索引1开始往后看,一旦发现这个数小于mid就赶快拿下来(保证全部小于mid),然后下一个数一点是作为偶数下标的数,无论这个数多大,这样让后面奇数的选择更多。这个贪心策略是最优的,因为你下一个数只能作为偶数下标的数了(两个数相邻),这样给了后面的数更多的可能成为奇数下标的数。
偶数同理。
代码:
#include<cstdio>
using namespace std;
int N,K;
int A[2<<17];
main()
{scanf("%d%d",&N,&K);for(int i=0;i<N;i++)scanf("%d",&A[i]);int L=0,R=1e9;while(R-L>1){int M=L+R>>1;bool ok=false;for(int tm=0;tm<2;tm++){int wt=tm;int cnt=0;for(int i=0;i<N;i++){if(wt==1){wt=0;cnt++;}else if(A[i]<=M){wt=1;cnt++;}}if(cnt>=K)ok=true;}if(ok)R=M;else L=M;}printf("%d\n",R);
}