bzoj1857 传送带 三分

       很早看到的三分法,竟然在今天用到了(显然已我的智商是想不到的)。然而发现自己并不会证明o(╯□╰)o,但是除了最关键的一步其它还是会的>_<。

       首先,我们用三分法,最基本的是要证明那个人一定是沿着如下路径走的:从A沿着AB走一段,再穿越到CD上某一点,最后到终点。证明如下:不妨假设p>q>r,因为当r>max(p,q)时没什么好讨论的,而p,q的大小没什么关系。那么假设这人从AB上一点X离开,那么如果它不沿着刚刚的路径,则它一定会沿着某个路径回到AB上一点Y,显然X->Y的最快方法是沿着AB走,因为这样距离最短而速度最快。证完。

       那么,如果我们假设它从AB上一点X出发到CD上一点Y再到终点,那么当X为定点时,时间与CY长度是成单峰函数的,证明如下:


       当s>=q时,显然时间随着CY的增大而减小,显然是单峰函数,因此不妨设s<q。过点X作XH⊥CD,显然当Y在CH上时时间增大,不做讨论。当Y在HD上时,设XH=h,HY=t,那么Y点比D点的时间节约(当Y点比D点时间长时该式为负号):t/q-(sqrt(t^2+h^2)-h)/s=t/q+h/s-sqrt(t^2+h^2)/s,显然sqrt(t^2+h^2)增长是没有t的增长快的,因此一开始该式为正数,时间减少;但是当t增大时,sqrt(t^2+h^2)的增大速度不断变快最终趋向于t的增大速度,不要忘了q>s,所以该式最终会变为负数并且一定会越变越小,时间不断增大。综上所述:时间先单调递减再单调递增,证完。

       然而我并不会证明从AB上一点X离开的最优时间,这个函数与AX成单峰函数关系。。。算了先挖个坑,谁会请告诉我>_<。AC代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#define eps 1e-3
using namespace std;

int ax,bx,cx,dx,ay,by,cy,dy,p,q,r;
double dist(double x1,double y1,double x2,double y2){
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
double solve(double u,double v){
	double lx=cx,ly=cy,rx=dx,ry=dy,x1,x2,y1,y2,t1,t2;
	while (abs(lx-rx)>eps || abs(ly-ry)>eps){
		x1=(lx+lx+rx)/3; x2=(x1+rx)/2; y1=(ly+ly+ry)/3; y2=(y1+ry)/2;
		t1=dist(x1,y1,dx,dy)/q+dist(x1,y1,u,v)/r;
		t2=dist(x2,y2,dx,dy)/q+dist(x2,y2,u,v)/r;
		if (t1<t2){ rx=x2; ry=y2; } else{ lx=x1; ly=y1; }
	}
	return dist(ax,ay,u,v)/p+dist(lx,ly,dx,dy)/q+dist(lx,ly,u,v)/r;
}
int main(){
	scanf("%d%d%d%d%d%d%d%d",&ax,&ay,&bx,&by,&cx,&cy,&dx,&dy);
	scanf("%d%d%d",&p,&q,&r);
	double lx=ax,ly=ay,rx=bx,ry=by,x1,x2,y1,y2;
	while (abs(lx-rx)>eps || abs(ly-ry)>eps){
		x1=(lx+lx+rx)/3; x2=(x1+rx)/2; y1=(ly+ly+ry)/3; y2=(y1+ry)/2;
		if (solve(x1,y1)<solve(x2,y2)){ rx=x2; ry=y2; } else{ lx=x1; ly=y1; }
	}
	printf("%.2f\n",solve(lx,ly));
	return 0;
}

by lych

2016.1.5

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值