来写一个三分套三分的写法。
我们发现对于一个 ((a,b)),式子即为 (x+y+frac{b}{a}x+frac{a}{b}y),所以之和 (frac{b}{a}) 有关,我们三分 (frac{b}{a}),关键是如何快速找到最大值。我们发现这是一条直线,答案是与y轴和x轴交点到原点的距离和,那么显然答案是在上凸包上,且在上凸包上具有三分性,再来个三分即可。
#include<bits/stdc++.h>
using namespace std;
const double inf=1e18;
const double eps=1e-14;
struct node{
double x,y;
friend bool operator < (node a,node b){
if(a.x==b.x)return a.y<b.y;
return a.x<b.x;
}
}p[1000005],stk[1000005];
int n,top;
double slope(node a,node b) {
if(a.x==b.x)return b.y>=a.y?inf:-inf;
return (b.y-a.y)/(b.x-a.x);
}
double get(double K,int id){
return stk[id].x*(K+1)+stk[id].y*(1/K+1);
}
double check(double K){
int l=1,r=top;
double ret=max(get(K,1),get(K,top));
while (l<r-1){
int m1=l+(r-l+1)/3;
int m2=r-(r-l+1)/3;
if(get(K,m1)>get(K,m2))r=m2;
else l=m1;
}
return max(ret,max(get(K,l),get(K,r)));
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lf%lf",&p[i].x,&p[i].y);
}
sort(p+1,p+1+n);
for(int i=1;i<=n;i++){
while(top>1&&slope(stk[top-1],stk[top])<=slope(stk[top],p[i]))top--;
stk[++top]=p[i];
}
double l=0,r=1e9;
while(r-l>eps){
double m1=l+(r-l)/3;
double m2=r-(r-l)/3;
if(check(m1)<check(m2))r=m2;
else l=m1;
}
printf("%.4lf
",min(check(l),check(r)));
return 0;
}