2017.9.9 传送带 失败总结

来源:互联网 发布:glenn medeiros 知乎 编辑:程序博客网 时间:2024/06/07 04:02

这个题、、是数学题

首先你必须有数学直觉,就是把题目化成用数学表示的式子、、

显然是ab走一段 中间走一段 cd走一段

所以最暴力的做法是枚举ab从哪里出,cd从哪里进。

所以实际上我们是在找两个点

设第二个点为q,第一个点为p

那我们就需要证明cd上的q到p的函数为单峰的

证明:点击打开链接

但其实这一个证明是不完全的、还需要证明,对于   无论第二个点q在什么位置,ab上的点的最优值是单峰的、

证明也很简单,,我们已经知道  随着点p越来越远,   所有的q的最优值一定是先减后增(或先增后减),

函数就变成了   ap/v1 + 一个单峰函数

由于ap/v1是一次函数,它的二阶导数为0

所以这个函数并不影响右边的单峰函数的峰值情况

所以复合函数依然是单峰函数


如果看不懂可以感受一下、画个图就明白了




然后就是三分了,知道两个函数都有单峰的性质就可以三分套三分了


码:

#include<iostream>#include<cstdio> #include<cmath>using namespace std;#define eps 1e-5double ax,ay,bx,by,cx,cy,dx,dy,p,q,r;double chk(double x,double y){double ans=sqrt((ax-x)*(ax-x)+(ay-y)*(ay-y))/p;double llx=cx,lly=cy,rrx=dx,rry=dy;while(fabs(llx-rrx)>eps||fabs(lly-rry)>eps){double lrx=(2*llx+rrx)/3,lry=(2*lly+rry)/3,rlx=(llx+2*rrx)/3,rly=(lly+2*rry)/3;            double  t1= sqrt((lrx-x)*(lrx-x)+(lry-y)*(lry-y))/r+ sqrt((lrx-dx)*(lrx-dx)+(lry-dy)*(lry-dy))/q ,t2=  sqrt((rlx-x)*(rlx-x)+(rly-y)*(rly-y))/r+ sqrt((rlx-dx)*(rlx-dx)+(rly-dy)*(rly-dy))/q   ;if(t1<t2){rrx=rlx;rry=rly;}else {llx=lrx;lly=lry;}}ans+=sqrt((llx-x)*(llx-x)+(lly-y)*(lly-y))/r+ sqrt((llx-dx)*(llx-dx)+(lly-dy)*(lly-dy))/q;return ans;}int main(){scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&ax,&ay,&bx,&by,&cx,&cy,&dx,&dy);scanf("%lf%lf%lf",&p,&q,&r);double llx=ax,lly=ay,rrx=bx,rry=by;while(fabs(llx-rrx)>eps||fabs(lly-rry)>eps){double lrx=(2*llx+rrx)/3,lry=(2*lly+rry)/3,rlx=(llx+2*rrx)/3,rly=(lly+2*rry)/3;if(chk(lrx,lry)<chk(rlx,rly)){rrx=rlx;rry=rly;}else{llx=lrx;lly=lry;}}printf("%.2lf",chk(llx,lly));}