CF373C-Counting Kangaroos is Fun

题意

\(n\)只袋鼠,每只袋鼠有一个体积,如果一个袋鼠的体积小于等于另一个袋鼠体积的一半,那么这个袋鼠就可以被那一个袋鼠装进袋里。一个装了袋鼠的袋鼠不能再装或被装。被装进袋子的袋鼠就看不到了。

问如何装袋让能看到的袋鼠最少。

分析

这是一个贪心问题。

首先,如果一个袋鼠能装另一个袋鼠,那么装必定是最优的。

把袋鼠按体积从小到大排好序,对于第\(x,y (x<y)\)号袋鼠,如果\(y\)号能装\(x\)号,那么\(y\)号及其后面的必定可以装下\(x\)号及其前面的。如果\(y\le \frac{n}{2}\)那么装的比被装的多,所以把\(y\)后移是不会影响答案。

所以我们得到了贪心的方法,把整个序列排序分成两半,前面一半被后面一半装,得到的肯定是最优的。

代码

#include<cstdio>
#include<cctype>
#include<algorithm>
using namespace std;
int read() {
	int x=0,f=1;
	char c=getchar();
	for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
	for (;isdigit(c);c=getchar()) x=x*10+c-'0';
	return x*f;
}
int main() {
#ifndef ONLINE_JUDGE
	freopen("test.in","r",stdin);
#endif
	int n=read(),ans=0;
	static int a[500005];
	for (int i=1;i<=n;++i) a[i]=read();
	sort(a+1,a+n+1);
	for (int i=1,j=(n>>1)+1;i<=(n>>1) && j<=n;++i) {
		for (;j<n && a[i]*2>a[j];++j);
		if (a[i]*2<=a[j]) ++ans,++j;
	}
	printf("%d\n",n-ans);
	return 0;
}
posted @ 2017-07-12 20:00  permui  阅读(224)  评论(0编辑  收藏  举报