数学荣获 74 分,是为波特
其实是数学题。先猜个
然后你发现判定每个区间是否合法并不好做……如果是双指针发现后面又不存在单调性。
那可以考虑拆成两半,算一下每个点为左端点前半的半圆能延伸到多远,作为右端点同理(因为发现只考虑一半的话,随着半径增加,每个坐标上需要的空间也是增加的),分别记为
那判定一个区间是否合法就比较容易了。问题在怎么求这个
当前正在算
LL n,A,B;
LL dp[10005];
DB L[10005],R[10005];
DB x[10005],y[10005],h;
int main(){
n=read(),h=read(),A=read(),B=read();
for(LL i=1;i<=n;++i) x[i]=read(),y[i]=read();
for(LL i=1;i<=n;++i)
{
L[i]=min((x[n]-x[i])/2,h-y[i]);
for(LL j=i+1;j<=n;++j)
{
if(x[j]-x[i]>L[i]) break;
DB r1=h-y[j];
DB a=1,b=2*x[i]-2*x[j]-2*h+2*y[j],c=(x[i]-x[j])*(x[i]-x[j])+(h-y[j])*(h-y[j]);
DB r2=(-b+sqrt(b*b-4*a*c))/(2*a);
L[i]=min(L[i],max(r1,r2));
}
L[i]*=2;
}
for(LL i=1;i<=n;++i)
{
R[i]=min((x[i]-x[1])/2,h-y[i]);
for(LL j=i-1;j;--j)
{
if(x[i]-x[j]>R[i]) break;
DB r1=h-y[j];
DB a=1,b=2*x[j]-2*x[i]-2*h+2*y[j],c=(x[i]-x[j])*(x[i]-x[j])+(h-y[j])*(h-y[j]);
DB r2=(-b+sqrt(b*b-4*a*c))/(2*a);
R[i]=min(R[i],max(r1,r2));
}
R[i]*=2;
}
memset(dp,63,sizeof dp);
dp[1]=A*(LL(h)-y[1]);
for(LL i=2;i<=n;++i) for(LL j=1;j<i;++j) if(x[j]+L[j]>=x[i] && x[i]-R[i]<=x[j]) dp[i]=min(dp[i],dp[j]+A*(LL(h)-(LL)y[i])+LL((LL)x[i]-(LL)x[j])*((LL)x[i]-(LL)x[j])*B);
if(dp[n]==dp[0]) puts("impossible");
else write(dp[n]),puts("");
return 0;
}