当答案具有可二分性时,我们可以用二分答案来解决。但是,如果要求出凸性函数或凹性函数的最值时,二分就毫无用武之地了,这时,我们就可以用三分法来求出答案。
一个凸性序列/凹性序列通俗的说法就是在该序列最大值/最小值的左边满足不严格单调递增/递减,右边满足不严格单调递减/递增。如1,2,3,6,4是一个凸性序列,而5,4,4,3,1,2,4,6是一个凹性序列(见下图),而图中的6和1就分别是两个序列的最值。、
与二分法类似的是,三分法也先取下界(记作l)和上界(记作r)的中间值(记作midl),随后,再取midl与r的中间值(记作midr)。接下来,我们要比较midl和midr所在的元素哪一个更接近最值,并依此更新上界和下界。不断重复以上操作,直至l>=r,则此时的l就是答案。
具体实现后得出的代码如下:
//这里以在一个凸性序列中查找元素为例
int find(int l,int r,int v)//l存储上界,r存储下界,v即为目标元素
{
if(l>=r) return l;//返回答案
int midl=(l+r)>>1,midr=(midl+r)>>1;
//比较midl与midr的大小
if(sum[midl]>sum[midr]) return find(l,midr);//若midl大于midr,说明最大值在左侧区间
return find(midl,r);//反之,说明最大值在右侧区间
}