三分

之前听说过三分然鹅一直妹有写.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);	
	}
}
posted @ 2020-08-29 20:08  千载煜  阅读(302)  评论(0编辑  收藏  举报