题目
思路
乍一看是三分题,仔细一看不简单,再想想,还是三分题,虽然题目将很多个二次函数放在一起,但可以发现,他们都是开口向上的或直线,又取最大值,画出图像,可以发现尽管最后的图像曲折,但还是一个单峰函数,这时我们就可以使用三分法查找答案了
三分法
首先我们取到定义域的端点L,R;
取两个三分点m1=L+(R-L)/3,m2=R-(R-L)/3;
以该题找最小值为例
我们每次对比m1,m2,大者一端端点更新为mx,因为小者更接近答案,又是单峰函数故被舍弃的一段区域肯定不存在答案,如此循环,直到R-L(精度)达到要求;
AC代码
#include <iostream>
using namespace std;
int a[10005]={0};
int b[10005]={0};
int c[10005]={0};
int main()
{
int round=0;scanf("%d",&round);
for(int ro=0;ro<round;ro++)
{
int n=0;scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d%d%d",a+i,b+i,c+i);
}
double l=0,r=1000;
while(r-l>1e-15)//精度
{
double m1=l+(r-l)/3;
double m2=r-(r-l)/3;
double s1,s2;
s1=m1*m1*a[0]+m1*b[0]+c[0];
s2=m2*m2*a[0]+m2*b[0]+c[0];
for(int i=1;i<n;i++)//取最大的函数值
{
s1=max(s1,m1*m1*a[i]+m1*b[i]+c[i]);
s2=max(s2,m2*m2*a[i]+m2*b[i]+c[i]);
}
if(s1>s2)
{
l=m1;
}
else
{
r=m2;
}
}
double ans;
ans=r*r*a[0]+r*b[0]+c[0];
for(int i=1;i<n;i++)//求出该位的答案
{
ans=max(ans,r*r*a[i]+r*b[i]+c[i]);
}
printf("%.4lf\n",ans);
}
return 0;
}