我用的二分模板是
int l=0,r=1e9+1;
while(l+1<r){
int mid=(l+r)/2;
if(check(mid)) ? = mid;
else ? = mid;
}
由于l+1<r是判断条件,所以当l等于r-1的时候无法跑check,这时候就将边界设置为最小值-1,和最大值+1。如果无法设置,最后单独判断一下l+1也可以。
4176. 愤怒的牛
题目抽象:从n个数中选出m个数,要求这m个数之间的最大的差值最小为多少。
绝对正确:枚举n个数,枚举m个数。O(n*m)
二分:二分这个差值最小,利用贪心思想,每次遍历到的这个数一旦比上一个数大于等于这个差值,就答案自加,最后比较答案是否大于等于m,如果是,说明答案符号要求,最小一定在大于等于这个数。答案具有二段性。
4178. 数列分段 II
题目抽象:将n个数,连续的分成m段,求m个段中和的最大值最小是多少。(每段至少一个数)
二分:本题需要注意可能被最大最小搞晕,check函数的参数一定要明确,是和的最大值,至于这个最大值是最大还是最小,是返回的事情。
由此只需要贪心的去找,当每段和的最大值为mid时,每次都分成最大能分的(<=mid),是否可以分成m段,如果分成的段数小于m段,说明一定可以m成更小或者等于mid的最大值。如果段数大于m,说明这个最大值太小了,分了好多,答案不可能是。
680. 剪绳子
肥肠煎蛋不说。