正解:半平面交
但是我们可以发现这么多线搞半平面的交集是一个半凸壳,没错于是我们就可以借用某一道好像是最大可视面积(其实是HNOI2008水平可视直线)还是什么的题的做法直接维护这个图形
然后我们就可以在每条线的交点处计算上下差值,至于为什么是交点……简单动态规划的最优值一定在某一个端点处取得大概是这样(其实我们可以用单调性来证明,毕竟线性函数)
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<iomanip>
#define LL long long
#define LF double
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define down(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
#define N 305
#define eps 1e-8
struct P
{
double x,y;
}d[N],l[N];
int n,m;
LL read()
{
LL d=0,f=1;char s=getchar();
while (s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while (s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
return d*f;
}
LF operator*(P a,P b)
{
return a.x*b.y-a.y*b.x;
}
LF operator/(P a,P b)
{
return a.x*b.x+a.y*b.y;
}
P operator+(P a,P b)
{
P t;
t.x=a.x+b.x; t.y=a.y+b.y;
return t;
}
P operator-(P a,P b)
{
P t;
t.x=a.x-b.x; t.y=a.y-b.y;
return t;
}
bool operator==(P a,P b)
{
return (a.x==b.x)&&(a.y==b.y);
}
LF dis(P a,P b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y*b.y)*(a.y*b.y));
}
P make(P a,P b)
{
P t;
t.x=(b.y-a.y)/(b.x-a.x);
t.y=a.y-a.x*t.x;
return t;
}
bool sortcom(P a,P b)
{
if (fabs(a.x-b.x)<=eps) return a.y<b.y;
return a.x<b.x;
}
double calx(int a,int b)
{
return (l[b].y-l[a].y)/(l[a].x-l[b].x);
}
double ans=0.0;
int s[N],stop=0;
double yup(double x)
{
double t=0.0;
fo(i,1,stop) t=max(t,l[s[i]].x*x+l[s[i]].y);
return t;
}
double ydown(double x)
{
int po=n;
double t=0.0;
fo(i,1,n-1)
if (d[i].x<x&&x<d[i+1].x)
{
po=i;
break;
}
if (po==n) return d[n].y;
P lin=make(d[po],d[po+1]);
t=lin.x*x+lin.y;
return t;
}
double crossx(P a,P b)
{
return (b.y-a.y)/(a.x-b.x);
}
void checks()
{
fo(i,1,stop)
cout<<l[s[i]].x<<' '<<l[s[i]].y<<endl;
cout<<endl;
}
int main()
{
n=read();
fo(i,1,n) d[i].x=read();
fo(i,1,n) d[i].y=read();
fo(i,1,n-1) l[i]=make(d[i+1],d[i]);
m=n-1;
sort(l+1,l+m+1,sortcom);
// checkl();
stop=0;
s[++stop]=1;
fo(i,2,m)
{
while (fabs(l[s[stop]].x-l[i].x)<=eps) stop--;
while (stop>1&&calx(s[stop-1],s[stop])>=calx(s[stop],i))
stop--;
s[++stop]=i;
}
cout<<setiosflags(ios::fixed);
cout.precision(3);
// checks();
ans=1e10;
fo(i,1,n)
{
ans=min(ans,yup(d[i].x)-d[i].y);
// cout<<ans<<endl;
}
// cout<<endl;
fo(i,1,stop-1)
{
double t=crossx(l[s[i]],l[s[i+1]]);
double ty=l[s[i]].x*t+l[s[i]].y;
ans=min(ans,ty-ydown(t));
// cout<<ans<<endl;
}
cout<<ans<<endl;
return 0;
}