Codeforces Round #651 (Div. 2) D

D. Odd-Even Subsequence
Codeforces Round #651 (Div. 2) D_第1张图片
题目大意:在a数组中 保留k个数字,如何代价最小的多少。
代价的算法 具体看题意:就是k数组中 min{max{奇数下标},max{偶数下标}}

解题思路:贪心加二分,二分全部的答案(即代价),然后检查能不能达到这个代价。

检查的思路: 我们只要 奇数下标或者偶数下标中 所以的数都小于mid值就能达到这个代价。
所以我们分为奇数下标和偶数下标来检查。
贪心策略:如果我们在检查奇数下标的时候,那么我们从索引1开始往后看,一旦发现这个数小于mid就赶快拿下来(保证全部小于mid),然后下一个数一点是作为偶数下标的数,无论这个数多大,这样让后面奇数的选择更多。这个贪心策略是最优的,因为你下一个数只能作为偶数下标的数了(两个数相邻),这样给了后面的数更多的可能成为奇数下标的数。
偶数同理。

代码:

#include
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);
}

你可能感兴趣的:(思维)