题目链接:https://codeforc.es/contest/1701/problem/C
一个青名题。二分类型
大意是,给出n个人编号 1-n,然后给出m个任务,每个任务a[i]对应一个值,这个值在1-n内,含义是a[i]这个人做这个任务时擅长的。
如果一个人去做他擅长的任务,那么他需要一个小时,否则需要两个小时。
n个人同时进行任务,求所需最短时间。
做法:有些二分逼近的思想。我们取一个mid去中和,比mid大的,我们记录出来,然后*2,这些需要用比mid小的任务数的人来中和
一次次逼近,直到最终答案。特别的,如果任务数小的那个人剩余可处理任务数是个奇数,则他能够提供的帮助要减少1,可以默认的是,
他所做的最后一次的奇数个任务所用的时间是2.
code:
#include<bits/stdc++.h> using namespace std; const int N=200005; int n,m,f[N],t,x; long long a,b; int main(){ cin>>t; for(;t--;){ scanf("%d%d",&m,&n); for(int i=1;i<=n;i++)scanf("%d",&x),f[x]++; int l=1,r=n,mid; while(l<=r){ mid=l+r>>1; a=b=0; for(int i=1;i<=m;i++) if(mid<=f[i]) a+=(f[i]-mid)*2; else b+=(mid-f[i])%2?mid-f[i]-1:mid-f[i]; if(a>b)l=mid+1; else r=mid-1; } printf("%d\n",l); for(int i=1;i<=m;i++)f[i]=0; } }