曾记否,到中流击水,浪遏飞舟。|

Moyyer_suiy

园龄:2年8个月粉丝:4关注:18

syoj.1827. 线段传送带题解

前情提要-三分

1827. 线段传送带

P2571 [SCOI2010] 传送带

省流:三分套三分。


在二维平面上有两个传送带,一个从 A 点到 B 点,一个从 C 点到 D 点,速度分别是 p 和 q,在平面内其他点的速度为 r。求 A 点到 D 点的最小速度。

考虑从 A 到 D 的路程一定是 AE+EF+FD,即通过这两个点连接这两个传送带,E 在第一个传送带上,F 同理在第二个。

所以答案求一个 (dis(A,E)/p+dis(E,F)/r+dis(F,D)/q)min。 这是个二元函数。

不妨将这个式子拆成两个函数,以确定参数 E,对于 f(E) 解出一个 F 使得 (dis(E,F)/r+dis(F,D)/q)min。那这个单峰函数可以用三分求最值。

同理,上式外面再套一个求 E 的式子,解出一个 E 使得 (dis(A,E)/p+f(E))min。这个单峰函数也可以用三分求解。

于是三分套三分。

#include<bits/stdc++.h>
#define db double
using namespace std;
const db eps=1e-6;
db ax,ay,bx,by,cx,cy,dx,dy,p,q,r;
db dis(db x,db y,db xx,db yy){
	return sqrt((yy-y)*(yy-y)+(xx-x)*(xx-x));
}
db f3(db x,db y,db xx,db yy){//E & F 
	return dis(x,y,xx,yy)/r+dis(xx,yy,dx,dy)/q;
}
db f2(db ex,db ey){//F
	db lx=cx,ly=cy,rx=dx,ry=dy;//CD
	while(dis(lx,ly,rx,ry)>eps){
		db x=(rx-lx)/3.0,y=(ry-ly)/3.0;
		db lmidx=lx+x,lmidy=ly+y,rmidx=rx-x,rmidy=ry-y;
		db ans1=f3(ex,ey,lmidx,lmidy);
		db ans2=f3(ex,ey,rmidx,rmidy);
		if(ans2-ans1>eps) rx=rmidx,ry=rmidy;
		else lx=lmidx,ly=lmidy;
	}
	return f3(ex,ey,lx,ly);
}
db f1(){//E
	db lx=ax,ly=ay,rx=bx,ry=by;
	while(dis(lx,ly,rx,ry)>eps){//AB
		db x=(rx-lx)/3.0,y=(ry-ly)/3.0;
		db lmidx=lx+x,lmidy=ly+y,rmidx=rx-x,rmidy=ry-y;
		db ans1=f2(lmidx,lmidy)+dis(ax,ay,lmidx,lmidy)/p;
		db ans2=f2(rmidx,rmidy)+dis(ax,ay,rmidx,rmidy)/p;
		if(ans2-ans1>eps) rx=rmidx,ry=rmidy;
		else lx=lmidx,ly=lmidy;
	}
	return f2(lx,ly)+dis(ax,ay,lx,ly)/p;
}
int main(){
	scanf("%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf",&ax,&ay,&bx,&by,&cx,&cy,&dx,&dy,&p,&q,&r);
	printf("%.2lf",f1());
	return 0;
}

本文作者:Moyyer_suiy

本文链接:https://www.cnblogs.com/Moyyer-suiy/p/17914384.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Moyyer_suiy  阅读(17)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起