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 ]\)。由此就可以进行三分。
\(\qquad\color{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\n",f(r)); } return 0; }