洛谷P2179 骑行川藏

什么毒瘤...

解:n = 1的,发现就是一个二次函数,解出来一个v的取值范围,选最大的即可。

n = 2的,猜测可以三分。于是先二分给第一段路多少能量,然后用上面的方法求第二段路的最短时间。注意剩余能量不足跑完第二段路的时候,返回INF。

正解是啥拉格朗日乘子法,完全搞不倒...

 1 /**
 2  * There is no end though there is a start in space. ---Infinity.
 3  * It has own power, it ruins, and it goes though there is a start also in the star. ---Finite.
 4  * Only the person who was wisdom can read the most foolish one from the history.
 5  * The fish that lives in the sea doesn't know the world in the land.
 6  * It also ruins and goes if they have wisdom.
 7  * It is funnier that man exceeds the speed of light than fish start living in the land.
 8  * It can be said that this is an final ultimatum from the god to the people who can fight.
 9  *
10  * Steins;Gate
11  */
12 
13 #include <bits/stdc++.h>
14 
15 const int N = 10010;
16 
17 double k[N], s[N], vv[N], E;
18 int n;
19 
20 namespace n1 {
21     inline void solve() {
22         double v = vv[1] + sqrt(E / s[1] / k[1]);
23         printf("%.10f\n", s[1] / v);
24         return;
25     }
26 }
27 
28 namespace n2 {
29 
30     inline double cal(double v) {
31         double ans = s[1] / v;
32         double delta = k[1] * s[1] * (vv[1] - v) * (vv[1] - v);
33         //printf("E - delta = %.10f \n", E - delta);
34         double v2 = vv[2] + sqrt((E - delta) / s[2] / k[2]);
35         if(v2 < 0) return 1e14;
36         //printf("v2 %.10f = %.10f + sqrt(%.10f / %.10f / %.10f) \n", v2, vv[2], E - delta, s[2], k[2]);
37         //printf("     =  %.10f + %.10f \n", vv[2], sqrt((E - delta) / s[2] / k[2]));
38         //printf("cal %.10f ->  %.10f + %.10f / %.10f \n", v, ans, s[2], v2);
39         return ans + s[2] / v2;
40     }
41 
42     inline void solve() {
43 
44         double l = 0, r = vv[1] + sqrt(E / s[1] / k[1]);
45         for(int i = 1; i <= 100; i++) {
46             double mid = (l + r) / 2;
47             //printf("l = %.10f r = %.10f \n", l, r);
48             double ml = mid - (r - l) / 6, mr = mid + (r - l) / 6;
49             double vl = cal(ml), vr = cal(mr);
50             if(vl > vr) {
51                 l = ml;
52             }
53             else {
54                 r = mr;
55             }
56         }
57         printf("%.10f\n", cal(r));
58         return;
59     }
60 }
61 
62 int main() {
63     scanf("%d%lf", &n, &E);
64     for(int i = 1; i <= n; i++) {
65         scanf("%lf%lf%lf", &s[i], &k[i], &vv[i]);
66     }
67 
68     if(n == 1) {
69         n1::solve();
70         return 0;
71     }
72 
73     if(n == 2) {
74         n2::solve();
75         return 0;
76     }
77 
78     return 0;
79 }
40分代码

猜你喜欢

转载自www.cnblogs.com/huyufeifei/p/10779552.html