1548: Design road (思维题 做法:三分找极值)
1548: Design road
Time Limit: 2 Sec Memory Limit: 256 Mb Submitted: 450 Solved: 237
Description
You need to design road from (0, 0) to (x, y) in plane with the lowest cost. Unfortunately, there are N Rivers between (0, 0) and (x, y).It costs c1 Yuan RMB per meter to build road, and it costs c2 Yuan RMB per meter to build a bridge. All rivers are parallel to the Y axis with infinite length.
Input
There are several test cases.
Each test case contains 5 positive integers N,x,y,c1,c2 in the first line.(N ≤ 1000,1 ≤ x,y≤ 100,000,1 ≤ c1,c2 ≤ 1000).
The following N lines, each line contains 2 positive integer xi, wi ( 1 ≤ i ≤ N ,1 ≤ xi ≤x, xi-1+wi-1 < xi , xN+wN ≤ x),indicate the i-th river(left bank) locate xi with wi width.
The input will finish with the end of file.
Output
For each the case, your program will output the least cost P on separate line, the P will be to two decimal places .
Sample Input
1 300 400 100 100 100 50 1 150 90 250 520 30 120
Sample Output
50000.00 80100.00
Hint
Source
给你两点(0,0) (x,y)
在这两点之间有n条平行于y轴的河流
修路每单位花费c1,搭桥每单位花费c2
问你到达(x,y)最小的花费是多少
把所有合河流移动到左边,所以肯定是直接从(0,0)搭桥到河流对岸的某点(sum,y)
sum是所有河流的宽度
然后从(sum,y)修路到目的地
现在想象一下
整条路径(包括路和桥)
路的两端是固定的
中间河流对面某点(sum,y)是不固定的
随着该点的移动,路径长度的不同的
所以花费也是不同的
所以找一个合适的y
使得花费最小
极值寻找问题,采用三分
三分寻找合适的y
使得花费最小
eps10的-3次方够了
#include<cstdio> #include<string> #include<cstdlib> #include<cmath> #include<iostream> #include<cstring> #include<set> #include<queue> #include<algorithm> #include<vector> #include<map> #include<cctype> #include<stack> #include<sstream> #include<list> #include<assert.h> #include<bitset> #include<numeric> using namespace std; typedef long long LL; #define max_v 1005 #define eps 1e-3 double dis(double x1,double y1,double x2,double y2) { return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); } int main() { int n; double x,y,c1,c2; while(~scanf("%d %lf %lf %lf %lf",&n,&x,&y,&c1,&c2)) { double sum=0,w,x1; for(int i=0;i<n;i++) { scanf("%lf %lf",&x1,&w); sum+=w; } sum=x-sum; double L=0,R=y,mid,mmid; while(R-L>eps) { mid=(L+R)/2.0; mmid=(mid+R)/2.0; double s1=dis(0,0,sum,mid)*c1+dis(sum,mid,x,y)*c2; double s2=dis(0,0,sum,mmid)*c1+dis(sum,mmid,x,y)*c2; if(s1>s2) L=mid; else R=mmid; } printf("%.2lf\n",dis(0,0,sum,mid)*c1+dis(sum,mid,x,y)*c2); } return 0; } /* 题目意思: 给你两点(0,0) (x,y) 在这两点之间有n条平行于y轴的河流 修路每单位花费c1,搭桥每单位花费c2 问你到达(x,y)最小的花费是多少 分析: 把所有合河流移动到左边,所以肯定是直接从(0,0)搭桥到河流对岸的某点(sum,y) sum是所有河流的宽度 然后从(sum,y)修路到目的地 现在想象一下 整条路径(包括路和桥) 路的两端是固定的 中间河流对面某点(sum,y)是不固定的 随着该点的移动,路径长度的不同的 所以花费也是不同的 所以找一个合适的y 使得花费最小 极值寻找问题,采用三分 三分寻找合适的y 使得花费最小 注意精度问题 eps10的-3次方够了 */