三分
之前听说过三分然鹅一直妹有写.jpg
三分用来解决单峰函数(例如二次函数)求最值的问题,经常用于一个东西套个三分
怎么三分
首先,我们肯定是把整个函数分成三段,像这样
其中\(l\)和\(r\)是三分时当前所在的位置
这里设求最大值
我们将的\([l,r]\)这一段三等分,三等分点分别是\(mid1,mid2\),如图
这里\(f(mid2)>f(mid1)\),所以将\(r\)跳到\(mid2\)更优一些
反之则将\(l\)跳到\(mid1\)
\(Code\)
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
inline ll read()
{
char ch=getchar();
ll x=0;bool f=0;
while(ch>'9'||ch<'0')
{
if(ch=='-')f=1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<3)+(x<<1)+(ch^48);
ch=getchar();
}
return f?-x:x;
}
const int N=10009;
const double eps=0.00000000000001;
int t,n,a[N],b[N],c[N];
double f(int num,double x){
return x*x*a[num]+b[num]*x+c[num];
}
int main(){
t=read();
while(t--){
n=read();
for(int i=1;i<=n;i++) a[i]=read(),b[i]=read(),c[i]=read();
double l=0,r=1000.0;
while(r-l>eps){
double mid1=l+(r-l)/3.0,mid2=r-(r-l)/3.0;
double a1=f(1,mid1),a2=f(1,mid2);
for(int i=2;i<=n;i++){
a1=max(a1,f(i,mid1));
a2=max(a2,f(i,mid2));
}
// printf("l=%.4lf,r=%.4lf,a1=%.4lf,a2=%.4lf\n",l,r,a1,a2);
if(a2<a1) l=mid1;
else r=mid2;
}
double ans=f(1,l);
for(int i=2;i<=n;i++)
ans=max(ans,f(i,l));
// printf("l=%.4lf\n",l);
printf("%.4lf\n",ans);
}
}