二分用到的挺多,三分用的少,但也不能忘。。。
二分我们常常用于一个具有单调性的情况中求解某值
而三分就像是求一个凸性或凹形函数时,来求那个凹凸点
一开始L=0,R=inf,然后也是不断缩小L与R的范围,逼近最值点
这里面有两个中间点mid1与mid2
mid1=(L+R)>>1
mid2=(mid1+R)>>1
然后判断mid1与mid2的大小关系,从而缩小不同范围
当while(L<R)不再满足条件时,答案也就呼之欲出
详细过程:
check()为三分的判断函数
1.check(mid1)>check(mid2),我们可以得知最值点位于mid2的左侧,我们通过R=mid2,将右边界逼近来缩小范围
因为如果mid1与mid2都在极点左侧,check(mid1)就比check(mid2)小,不满足条件。所以最值点只能在mid2左侧
2.check(mid1)<check(mid2),我们可以得知最值点一定位于mid1的右侧,我们将左边界缩小,L=mid1
为什么?如果最极点位于mid1的左侧,mid1<mid2,mid2也在右侧,那check的结果比较就与条件冲突
这讲的是凸形状,还有凹形状,正好相反
代码:
凸形状
两种写法:
int three(int l,int r) //找凸点
{ while(l < r-1) { int mid1 = (l+r)/2; int mid2 = (mid1+r)/2; if( check(mid1) > check(mid2) ) r = mid2; else l = mid1; } return f(l)>f(r)? l : r;
}
double three(double l,double r)
{ double mid1,mid2; while(r-l>=eps) { mid1=l+(r-l)/3; mid2=r-(r-l)/3; if(f(m1)<=f(m2)) l=mid1; else r=mid2; } return (mid1+mid2)/2;
}
这个题就可以用三分来做题目穿送
这里存一下二分的模板,没地方放了
bool check(int mid){ …… return ……;}
//模板一 找满足某个条件的第一个数
int binary1(int l, int r)
{while(l<r){int mid=(r+l)>>1;if(check(mid) r=mid;else l=mid+1;}return l;
}
//模板二 找满足某个条件的最后一个数
int binary1(int l, int r)
{while(l<r){int mid=(r+l+1)>>1;if(check(mid) l=mid;else r=mid-1;}return l;
}