题目链接
思路:先把k个团队的人数从大到小排序,我们发现s最小是num【1】,那么s最大是num【1】+num【2】?可是我们这样想的话容易被毒瘤数据tle,所以还得优化一下,我们可以想我们最优的方案是不是一辆车每次尽可能答案两个团队,同时人数是不是尽可能的满?所以我们可以枚举max(a【1】+a【k】、a【2】+a【k-1】。。。。),这个才是s的最大值,这样缩小了s的范围以后就可以通过枚举s求出最小值。
#include <bits/stdc++.h>
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);
}