算法背景:
二分与三分类似。
二分法利用的是函数的单调性。而三分法利用的是函数的单峰性。二次函数就是一个典型的单峰函数。三分法与二分法一样,它会不断缩小答案所在的求解区间,直到求出极值。
如图:
算法流程:
1、设当前求解的区间为 [l,r],令 m1=l+(r-l)/3,m2=r-(r-l)/3;
2、接着我们计算这两个点对应函数值 find(m1),find(m2)(类似于二分中的check);
3、 之后我们将两点中函数值更优的那个点称为好点 (若计算最大值,find后结果更大的那个点就称为好点,计算最小值等同理),而函数值较差的那个点称为坏点。我们可以证明,最优点与好点会在坏点的同侧。如上图,find(m1)>find(m2),所以m1是好点,m2 是坏点,因此最后的最优点会与m1一起在m2的左侧,即我们的求解区间由[l,r]变成[l,m2];
4、因此同理我们可以重复以上操作不断缩短求解区间,直至可以得出近似最优解(根据题目的精度要求)。
关键代码:
double l,r;//l与r根据题目要求自设范围
while(r-l>eps)//eps根据题目要求自设精度
{
double m1=l+(r-l)/3;
double m2=r-(r-l)/3;
if(find(m1)<find(m2)) l=m1;//find根据题目要求计算对应函数值
else r = m2;
}
附练习题:
1、[POJ 3737]UmBasketella:链接: poj3737 http://poj.org/problem?id=3737 三分模板
附我的讲解:http://blog.csdn.net/qianguch/article/details/78168318
2、[SCOI2010]传送带 链接: bzoj 1857 http://www.lydsy.com/JudgeOnline/problem.php?id=1857 三分套三分,有点难度
附我的讲解:http://blog.csdn.net/qianguch/article/details/77996221