https://loj.ac/problem/10013
题目描述
定义(F(x)=max(Si(x))),给出(n)个二次函数(S_i = ax^2 + bx + c) ,求(F(x))的最小值
思路
由于(S(x))要么是开口向上的二次函数,要么是单调增的一次函数,要么是常数,所以(F(x))也一定是一个单调函数,并且不是很显然的能用三分求解(我也不是特别知道为什么),就主要讲一下如何用三分。我们现在有一个已知区间([ L , R ]),那么(Lmid = L + ( R - L ) / 3,Rmid = R - ( R - L ) / 3) 。我们以开口向上的二次函数为例,如果(f(Lmid)< f(Rmid)),那么我们可以证明(Lmid)和最优点在(Rmid)的同侧,即区间可以缩小至([ L , Rmid ])。由此就可以进行三分。
(qquadcolor{red}{三分的要求必须是严格的单调函数,如果存在一段f(Lmid)= f(Rmid),就无法进行三分了})
代码
#include <bits/stdc++.h>
using namespace std;
const int MAXN=101000;
double a[MAXN],b[MAXN],c[MAXN];
int n;
double f(double x)
{
double maxx=-0x7fffffff;
for(int i=1;i<=n;i++)
maxx=max(maxx,a[i]*x*x+b[i]*x+c[i]);
return maxx;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lf%lf%lf",&a[i],&b[i],&c[i]);
double eps=1e-10,l=0,r=1000;
while(r>eps+l)
{
double lmid=l+(r-l)/3;
double rmid=r-(r-l)/3;
if(f(lmid)<=f(rmid))r=rmid;
else l=lmid;
}
printf("%.4lf
",f(r));
}
return 0;
}