二分用到的挺多,三分用的少,但也不能忘。。。
二分我们常常用于一个具有单调性的情况中求解某值
而三分就像是求一个凸性或凹形函数时,来求那个凹凸点
一开始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;
}
这个题就可以用三分来做题目穿送