1. 程式人生 > >Codeforces 866C Gotta Go Fast - 動態規劃 - 概率與期望 - 二分答案

Codeforces 866C Gotta Go Fast - 動態規劃 - 概率與期望 - 二分答案

you div 圖片 cin decision dot contains take als

You‘re trying to set the record on your favorite video game. The game consists of N levels, which must be completed sequentially in order to beat the game. You usually complete each level as fast as possible, but sometimes finish a level slower. Specifically, you will complete the i-th level in either F

i seconds or Si seconds, where Fi < Si, and there‘s a Pi percent chance of completing it in Fi seconds. After completing a level, you may decide to either continue the game and play the next level, or reset the game and start again from the first level. Both the decision and the action are instant.

Your goal is to complete all the levels sequentially in at most R total seconds. You want to minimize the expected amount of time playing before achieving that goal. If you continue and reset optimally, how much total time can you expect to spend playing?

Input

The first line of input contains integers N

and R 技術分享圖片, the number of levels and number of seconds you want to complete the game in, respectively. N lines follow. The ith such line contains integers Fi, Si, Pi (1 ≤ Fi < Si ≤ 100, 80 ≤ Pi ≤ 99), the fast time for level i, the slow time for level i, and the probability (as a percentage) of completing level i with the fast time.

Output

Print the total expected time. Your answer must be correct within an absolute or relative error of 10 - 9.

Formally, let your answer be a, and the jury‘s answer be b. Your answer will be considered correct, if 技術分享圖片.

Examples input
1 8
2 8 81
output
3.14
input
2 30
20 30 80
3 9 85
output
31.4
input
4 319
63 79 89
79 97 91
75 87 88
75 90 83
output
314.159265358
Note

In the first example, you never need to reset. There‘s an 81% chance of completing the level in 2 seconds and a 19% chance of needing 8 seconds, both of which are within the goal time. The expected time is 0.81·2 + 0.19·8 = 3.14.

In the second example, you should reset after the first level if you complete it slowly. On average it will take 0.25 slow attempts before your first fast attempt. Then it doesn‘t matter whether you complete the second level fast or slow. The expected time is 0.25·30 + 20 + 0.85·3 + 0.15·9 = 31.4.


  題目大意 一個人打遊戲,需要不超過$R$秒通過$n$關,第$i$關有$P_{i}$的概率用$F_{i}$秒通過,$\left(1 - P_{i}\right)$的概率用$S_{i}$通過($F_{i} < S_{i}$),通過每一關可以選擇重置遊戲,然後從頭開始,或者去打下一關。問不超過$R$秒通過所有關卡的期望耗時。

  轉移是顯然的。(如果這個都不會,請自定百度“概率dp入門題”)

  然後發現轉移有環,還要做決策?

  然後列方程吧。。開心地發現不會解。

  可惜這裏是信息學競賽,不是數學競賽。由於轉移都需要 dp[0][0] 但是開始不知道它,所以考慮二分它,然後和推出來的 dp[0][0] 作比較。

  經過各種瞎猜和亂搞,可以發現一個神奇的事情

技術分享圖片

  然後就可根據它來確定一次check後,二分的範圍。

  另外,由於坑人的精度問題,所以最好不要寫while (l + eps < r) ,總之我這麽寫各種因為精度問題的TLE來了。

Code

 1 /**
 2  * Codeforces
 3  * Problem#866C
 4  * Accepted
 5  * Time: 62ms
 6  * Memory: 4316k
 7  */
 8 #include <bits/stdc++.h>
 9 using namespace std;
10 typedef bool boolean;
11 
12 const long double eps = 1e-9;
13 const int binary_lim = 80;
14 
15 int n, R;
16 int *fs, *ss;
17 double *ps;
18 
19 inline void init() {
20     scanf("%d%d", &n, &R);
21     fs = new int[(n + 1)];
22     ss = new int[(n + 1)];
23     ps = new double[(n + 1)];
24     for(int i = 1; i <= n; i++) {
25         scanf("%d%d", fs + i, ss + i);
26         cin >> ps[i];
27         ps[i] *= 0.01;
28     }
29 }
30 
31 boolean vis[51][5105];
32 double f[51][5105];
33 
34 double dfs(int d, int t, double &mid) {
35     if(d == n)    return (t > R) ? (mid) : (0);
36     if(vis[d][t])    return f[d][t];
37     vis[d][t] = true;
38     f[d][t] = (dfs(d + 1, t + fs[d + 1], mid) + fs[d + 1]) * ps[d + 1] + (dfs(d + 1, t + ss[d + 1], mid) + ss[d + 1]) * (1 - ps[d + 1]);
39     if(mid < f[d][t])    f[d][t] = mid;
40     return f[d][t];
41 }
42 
43 double dp(double mid) {
44     memset(vis, false, sizeof(vis));
45     return dfs(0, 0, mid);
46 }
47 
48 inline void solve() {
49     double l = 0, r = 1e9;
50     for(int i = 0; i < binary_lim; i++) {
51         double mid = (l + r) / 2;
52         if(dp(mid) < mid)    r = mid;
53         else    l = mid;
54     }
55     printf("%.9lf", l);
56 }
57 
58 int main() {
59     init();
60     solve();
61     return 0;
62 }

Codeforces 866C Gotta Go Fast - 動態規劃 - 概率與期望 - 二分答案