2019-2020 ICPC, NERC, Southern and Volga Russian Regional Contest B. The Feast and the Bus (经典贪心)

题目链接
2019-2020 ICPC, NERC, Southern and Volga Russian Regional Contest B. The Feast and the Bus (经典贪心)_第1张图片
思路:先把k个团队的人数从大到小排序,我们发现s最小是num【1】,那么s最大是num【1】+num【2】?可是我们这样想的话容易被毒瘤数据tle,所以还得优化一下,我们可以想我们最优的方案是不是一辆车每次尽可能答案两个团队,同时人数是不是尽可能的满?所以我们可以枚举max(a【1】+a【k】、a【2】+a【k-1】。。。。),这个才是s的最大值,这样缩小了s的范围以后就可以通过枚举s求出最小值。

#include 
using namespace std;
const int maxn=5e5+1;
typedef long long ll;
bool cmp(int a,int b)
{
	return a>b;
}
int n,k,num[maxn],t,maxx=0;
int main()
{
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;++i) scanf("%d",&t),num[t]++;
	sort(num+1,num+1+k,cmp);
	for(int i=1,j=k;i<=j;++i,--j)
	if(i!=j) maxx=max(maxx,num[i]+num[j]);
	else maxx=max(maxx,num[i]);
	ll ans=0x3f3f3f3f3f;
	for(int s=num[1];s<=maxx;++s)
	{
		int l=1,r=k,time=0;
		while(l<=r)
		{
			time++;
			if(l!=r&&num[l]+num[r]<=s) l++,r--;//如果容量够,就让两个队伍上车 
			else l++;//如果不够,就让容量大的队伍上 
		}
		ans=min(ans,1ll*time*s); 
	}
	printf("%lld\n",ans);
}

你可能感兴趣的:(贪心)