1. 程式人生 > >HDU 3400 Line belt (三分套三分)

HDU 3400 Line belt (三分套三分)

while freopen ios logs 三分 分享 -1 txt pri

http://acm.split.hdu.edu.cn/showproblem.php?pid=3400

題意:

有兩條帶子ab和cd,在ab上的速度為p,在cd上的速度為q,在其它地方的速度為r。現在計算從a出發到達d的最少花費時間。

思路:

分別在ab和cd兩段線路上找一個轉折點,然後就是由這三段路組成。

設ab上的線路長度為x,cd上的為y,其余為z。

那麽總的時間就是技術分享,分開來考慮,技術分享,F(x)是個單調遞增函數,G(y,z)是個凹性函數。

那麽總的T函數還是一個凹性函數,那麽就可以三分了,對ab進行一次三分,然後繼續對cd進行三分。

 1 #include<iostream>
 2
#include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<vector> 6 #include<stack> 7 #include<queue> 8 #include<cmath> 9 #include<map> 10 #include<set> 11 using namespace std; 12 typedef long long ll; 13 typedef pair<int
,int> pll; 14 const int INF = 0x3f3f3f3f; 15 const int maxn = 300000+5; 16 17 const double eps=1e-8; 18 19 struct node 20 { 21 double x,y; 22 }a,b,c,d; 23 24 double p,q,r; 25 26 double getdis(node t1, node t2) 27 { 28 return sqrt((t2.y-t1.y)*(t2.y-t1.y)+(t2.x-t1.x)*(t2.x-t1.x));
29 } 30 31 double solve_cd(node ab) 32 { 33 node mid, midd; 34 node t1=c,t2=d; 35 double d1,d2; 36 do 37 { 38 mid.x=(t1.x+t2.x)/2; 39 mid.y=(t1.y+t2.y)/2; 40 midd.x=(mid.x+t2.x)/2; 41 midd.y=(mid.y+t2.y)/2; 42 d1=getdis(mid,ab)/r+getdis(d,mid)/q; 43 d2=getdis(midd,ab)/r+getdis(d,midd)/q; 44 if(d1<d2) t2=midd; 45 else t1=mid; 46 }while(getdis(t1,t2)>=eps); 47 return min(d1,d2); 48 } 49 50 double solve_ab() 51 { 52 node mid, midd; 53 node t1=a,t2=b; 54 double ans1,ans2; 55 do 56 { 57 mid.x=(t1.x+t2.x)/2; 58 mid.y=(t1.y+t2.y)/2; 59 midd.x=(mid.x+t2.x)/2; 60 midd.y=(mid.y+t2.y)/2; 61 double d1=getdis(mid,a); 62 double d2=getdis(midd,a); 63 ans1=d1/p+solve_cd(mid); 64 ans2=d2/p+solve_cd(midd); 65 if(ans1<ans2) t2=midd; 66 else t1=mid; 67 }while(getdis(t1,t2)>=eps); 68 return min(ans1,ans2); 69 } 70 71 int main() 72 { 73 //freopen("in.txt","r",stdin); 74 int T; 75 scanf("%d",&T); 76 while(T--) 77 { 78 scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y,&c.x,&c.y,&d.x,&d.y); 79 scanf("%lf%lf%lf",&p,&q,&r); 80 printf("%.2f\n",solve_ab()); 81 } 82 return 0; 83 }

HDU 3400 Line belt (三分套三分)