题意:
有n个人(带顺序),对i,如果前面有ai个人加入,那么i会加入
你可以强迫任何一个人加入,问想要加入人数达到m的最小强迫次数为多少
解析:
假设你一定要强迫一个人,那么最优方案为强迫第一个不加入的人,因为从加入的人开始后面的人加入的可能性变大,越前面加入,开始的越早
但是在不知道强迫多少人的情况下,你处理起来会很复杂,因为你在遇到一个不加入的人的时候,你要考虑后面的加入的人是不是已经够了,这样复杂度就变成n^n了
对于这种情况,有种强大的方法:二分
二分的好处就是简化复杂度,用假设的已知代替未知
对于求一个最多或最少的问题,通常可以用二分来简单地解决
像这题,用二分得到确切的强迫次数,那么就可以直接从前往后遍历了
代码:
扫描二维码关注公众号,回复:
2479063 查看本文章
int a[200009];
int check(int t,int n,int m){
int now=0;
for(int i=1;i<=n;i++){
if(a[i]>now){
if(t){t--,now++;}
else continue;
}
else{
now++;
}
}
if(now>=m)return 1;
return 0;
}
int main(){
int n=read(),m=read();
for1(i,1,n)a[i]=read();
if(check(0,n,m))return 0*printf("0\n");
int l=0,r=m;
while(r-l>1){
int mid=l+r>>1;
if(check(mid,n,m))r=mid;
else l=mid;
}
printf("%d\n",r);
}