1548: Design road (思维题 做法:三分找极值)
Posted yinbiao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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)最小的花费是多少
![技术分享图片](https://image.cha138.com/20210807/c999c29dc75a4b3f8584bc9529cc74b3.jpg)
把所有合河流移动到左边,所以肯定是直接从(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 ",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次方够了 */
以上是关于1548: Design road (思维题 做法:三分找极值)的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ 1257: [CQOI2007]余数之和sum神奇的做法,思维题
Codeforces 908 F. New Year and Rainbow Roads(思维)
Codeforces 908 F. New Year and Rainbow Roads(思维)