三分法和二分法有些类似,二分处理的是递增/减的函数,而三分处理的是先递增后递减(或相反)的函数的最值。
int lm=l+(r-l)/3,rm=r-(r-l)/3;
如上图,lm<rm,则函数最小值在[l,rm]间,再继续三分即可。
反向也是同理,如上图,最大值在[lm,r]之间。
现在我们来做一道模板题:给一函数,该函数在任意Y>0的情况下x在[0,100]内有极小值,求之。
按照思路套上代码即可,代码如下:
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #define eps 1e-7 5 using namespace std; 6 double y; 7 double val(double x){ 8 return 6*x*x*x*x*x*x*x+8*x*x*x*x*x*x+7*x*x*x+5*x*x-y*x; 9 } 10 double solve(double l,double r){ 11 while(l+eps<r){ 12 double lm=l+(r-l)/3,rm=r-(r-l)/3; 13 if(val(lm)<val(rm)) r=rm; 14 else l=lm; 15 } 16 return val(l); 17 } 18 int main() 19 { 20 int T; scanf("%d",&T); 21 while(T--){ 22 scanf("%lf",&y); 23 printf("%.4lf\n",solve(0,100.0)); 24 } 25 }