http://www.lydsy.com/JudgeOnline/problem.php?id=1857 (题目链接)

题意

  给出两条线段AB和CD,在AB上的速度为P,在CD上的速度为Q,在AB,CD之外的平面上速度为R,求从A到D的最短时间。

Solution

  三分套三分。

  三分法是个很基础的东西,当问题的答案呈现出的函数图像是单峰的那么就可以使用三分法求出它的最值,具体操作与二分法差不多。

  可这道题为什么可以用三分法呢,也就是说它为什么是单峰的,我也不会= =,果断翻题解。 
  

  首先,我们用三分法,最基本的是要证明那个人一定是沿着如下路径走的:从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成单峰函数关系。。。

  于是就这样挖了个坑。。。最关键的地方还是没有讲到。

代码

// bzoj1857
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<set>
#define eps 1e-9
#define inf 2147483640
#define LL long long
#define free(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);
using namespace std;
inline LL getint() {
LL x=0,f=1;char ch=getchar();
while (ch>'9' || ch<'0') {if (ch=='-') f=-1;ch=getchar();}
while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();}
return x*f;
} int ax,bx,cx,dx,ay,by,cy,dy,p,q,r; double dis(double x1,double y1,double x2,double y2) {
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
double cal(double x,double y) {
double x1,y1,x2,y2,t1,t2;
double lx=cx,ly=cy,rx=dx,ry=dy;
while (fabs(lx-rx)>eps || fabs(ly-ry)>eps) {
x1=lx+(rx-lx)/3;x2=lx+(rx-lx)/3*2;
y1=ly+(ry-ly)/3;y2=ly+(ry-ly)/3*2;
t1=dis(ax,ay,x,y)/p+dis(x,y,x1,y1)/r+dis(x1,y1,dx,dy)/q;
t2=dis(ax,ay,x,y)/p+dis(x,y,x2,y2)/r+dis(x2,y2,dx,dy)/q;
if (t1>t2) lx=x1,ly=y1;
else rx=x2,ry=y2;
}
//return min(t1,t2);
return dis(ax,ay,x,y)/p+dis(x,y,lx,ly)/r+dis(lx,ly,dx,dy)/q;
}
int main() {
scanf("%d%d%d%d",&ax,&ay,&bx,&by);
scanf("%d%d%d%d",&cx,&cy,&dx,&dy);
scanf("%d%d%d",&p,&q,&r);
double x1,x2,y1,y2,t1,t2;
double lx=ax,ly=ay,rx=bx,ry=by;
while (fabs(rx-lx)>eps || fabs(ry-ly)>eps) {
x1=lx+(rx-lx)/3;x2=lx+(rx-lx)/3*2;
y1=ly+(ry-ly)/3;y2=ly+(ry-ly)/3*2;
t1=cal(x1,y1);t2=cal(x2,y2);
if (t1>t2) lx=x1,ly=y1;
else rx=x2,ry=y2;
}
printf("%.2f",cal(lx,ly));
//printf("%.2f",min(t1,t2));
return 0;
}

  

【bzoj1857】 Scoi2010—传送带的更多相关文章

  1. BZOJ1857 Scoi2010 传送带 【三分】

    BZOJ1857 Scoi2010 传送带 Description 在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段.两条传送带分别为线段AB和线段CD.lxhgww在AB上的移动速度为P ...

  2. 2018.06.30 BZOJ1857: [Scoi2010]传送带(三分套三分)

    1857: [Scoi2010]传送带 Time Limit: 1 Sec Memory Limit: 64 MB Description 在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段 ...

  3. BZOJ1857 [Scoi2010]传送带 【三分法】

    题目链接 BZOJ1857 题解 画画图就发现实际上是在\(AB\)上和\(CD\)上分别选两个点\(E\),\(F\),使得\(t_{AE} + t_{EF} + t_{FD}\)最小 然后猜想到当 ...

  4. bzoj1857: [Scoi2010]传送带--三分套三分

    三分套三分模板 貌似只要是单峰函数就可以用三分求解 #include<stdio.h> #include<string.h> #include<algorithm> ...

  5. BZOJ1857[SCOI2010]传送带

    题目大意:平面上两条线段,一个人从一条线段的一个点到另一条线段的一个点,最小时间是多少 路径肯定是在一条线段上走一段,然后走平面,最后再走另一条线段,那么需要确定的就是在两条线段上走的距离,其他暴力算 ...

  6. [BZOJ1857][SCOI2010]传送带-[三分]

    Description 传送门 Solution 三分套三分.代码简单但是证明苦兮兮.. 假如我们在AB上选了一个点G,求到该点到D的最小时间. 图中b与CD垂直.设目前从G到D所耗时间最短的路径为G ...

  7. 【BZOJ1857】[Scoi2010]传送带 三分套三分

    [BZOJ1857][Scoi2010]传送带 Description 在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段.两条传送带分别为线段AB和线段CD.lxhgww在AB上的移动速度 ...

  8. 【BZOJ-1857】传送带 三分套三分

    1857: [Scoi2010]传送带 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 1077  Solved: 575[Submit][Status][ ...

  9. bzoj 1857: [Scoi2010]传送带 三分

    题目链接 1857: [Scoi2010]传送带 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 934  Solved: 501[Submit][Stat ...

  10. 【BZOJ1857】传送带(三分)

    [BZOJ1857]传送带(三分) 题面 Description 在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段.两条传送带分别为线段AB和线段CD.lxhgww在AB上的移动速度为P, ...

随机推荐

  1. C#FTP登入

    FtpWebRequest reqFTP; try { // 根据uri创建FtpWebRequest对象 reqFTP = (FtpWebRequest)FtpWebRequest.Create(n ...

  2. EventBus (四) Sticky事件

    什么是Sticky事件? 关于Sticky事件有的同学可能不是很熟悉,Sticky的意思是粘性的.在Android开 发中,Sticky事件只指事件消费者在事件发布之后才注册的也能接收到该事件的特殊类 ...

  3. Windows 2008 R2 配置 DNS 实现二级域名

    本文内容 域名解析 准备工作 安装 DNS 服务器 建立 DNS 区域 建立主机头 服务器网络设置 测试二级域名 IIS 建立 Web 站点 其他 DNS 服务 域名解析 域名解析,是域名到 IP 地 ...

  4. [转]curl_multi 实现准多进程发请求

    FROM : http://blog.sina.com.cn/s/blog_515b90d00100jtnv.html curl_multi函数族:curl_multi_closecurl_multi ...

  5. Socket Programming in C#--Introduction

    This is the second part of the previous article about the socket programming. In the earlier article ...

  6. salt-ssh

    1.生产---测试--开发 salt-runners salt-run manage.status#显示当前up或down的minion salt-run manage.down salt-run m ...

  7. 在c++程序中执行DOS命令

    转自博客:http://blog.csdn.net/ypist/article/details/8485049 #1,system()方式 在C盘根目录下新建文件夹,名称为12: system(&qu ...

  8. 自动化测试: sikuli,一个基于界面图像的gui测试框架

    http://www.sikuli.org/ license: MIT script language: Python 下面是他的一个hello world的例子,看看也挺有意思的. 开源的世界里有很 ...

  9. [CareerCup] 1.7 Set Matrix Zeroes 矩阵赋零

    1.7 Write an algorithm such that if an element in an MxN matrix is 0, its entire row and column are ...

  10. Linux及安全——模块

    Linux及安全——模块 一.模块的编译.生成.测试.删除 1.编写模块代码 编写:gedit test.c 查看:cat test.c 2.查看版本信息 3.编写Makefile obj-m :这个 ...