三分法主要解决的问题是在一个单峰函数上求极值,所谓单峰函数,就是函数图像只有一个峰的函数,就像这样(图一):
还有这样(图二):
三分法,顾名思义,就是要三分嘛,把当前区间分成三分,将中间的两个分界点记做
x
1
x_1
x1 和
x
2
x_2
x2,他们所对应的函数值分别是
y
1
y_1
y1 和
y
2
y_2
y2,假如我要求的这个函数是个凸函数(就像图一),那么我们就舍去函数值小的那一边,就像这样:
此时发现
y
2
y_2
y2 小于
y
1
y_1
y1,于是将
x
2
x_2
x2 ~
r
r
r 部分都舍去,因为很显然这部分满足单调性,
y
y
y 值都单调小于
y
1
y_1
y1,所以顶点一定不再这里面,然后一直缩缩缩,就找到答案了。
比较显然, F ( x ) F(x) F(x) 不可能有两个峰,这个想想就能明白,所以是个单峰函数。
代码如下:
#include <cstdio>
#include <algorithm>
using namespace std;
#define maxn 100010
#define db double
#define eps 1e-10
int T,n,a[maxn],b[maxn],c[maxn];
db S(int i,db x){return a[i]*x*x+b[i]*x+c[i];}
db F(db x){db re=0;for(int i=1;i<=n;i++)re=max(re,S(i,x));return re;}
int main()
{
scanf("%d",&T);while(T--)
{
scanf("%d",&n);for(int i=1;i<=n;i++)
scanf("%d %d %d",&a[i],&b[i],&c[i]);
db l=0,r=1000,x,y;while(r-l>eps){
x=l+(r-l)/3.0,y=x+(r-l)/3.0;
if(F(x)<F(y))r=y;else l=x;
}
printf("%.4lf\n",F(l));
}
}