toj 3086 Passage (不错)

Passage

时间限制(普通/Java):1000MS/3000MS 运行内存限制:65536KByte
总提交: 40 测试通过: 20

描述

Bill is a millionaire. But unfortunately he was trapped in a castle. There are only n passages to go out. For any passage i (1<=i<=n), Pi (0<=Pi<=1) denotes the probability that Bill will escape from this castle safely if he chose this passage. Qi (0<=Qi<=1-Pi) denotes the probability that there is a group of guards in this passage. And Bill should give them one million dollars and go back. Otherwise, he will be killed. The probability of this passage had a dead end is 1-Pi-Qi. In this case Bill has to go back. Whenever he came back, he can choose another passage.
We already know that Bill has M million dollars. Help Bill to find out the probability that he can escape from this castle if he chose the optimal strategy.

输入

The first line contains an integer T (T<=100) indicating the number of test cases.
The first line of each test case contains two integers n (1<=n<=1000) and M (0<=M<=10).
Then n lines follows, each line contains two float number Pi and Qi.

输出

For each test case, print the case number and the answer in a single line.
The answer should be rounded to five digits after the decimal point.
Follow the format of the sample output.

样例输入

 

3
1 10
0.5 0
2 0
0.3 0.4
0.4 0.5
3 0
0.333 0.234
0.353 0.453
0.342 0.532

 

样例输出

 

Case 1: 0.50000
Case 2: 0.43000
Case 3: 0.51458

 

题目来源

“光庭杯”第五届华中北区程序设计邀请赛 暨 WHU第八届程序设计竞赛

 

如果有两总选择 P1, Q1 and P2, Q2

先选第一条路被抓的概率为 ret1 = (1 - p1 - Q1) * Q2 + Q1  

先选第二条路被抓的概率为 ret2 = (1 - p2 - Q2) * Q1 + Q2

P1 / Q1 > P2 / Q2  => P1 * Q2 > P2 * Q1

ret1 - ret2 =  P2 * Q1 - P1 * Q2 < 0

所以优先选择第一条路

先按Pi / Qi 从大到小排序

dp[i][j] 表示到第 i 条路, 消耗 j million dollars的概率

 逃跑的概率 ret += dp[i-1][j] * Pi ( j <= k )

dp[i][j] = dp[i-1][j] * (1.0 - Pi - Qi) + dp[i-1][j-1] * Qi

 1 #include <stdio.h>
 2 #include <iostream>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 struct Node{
 7     double Pi, Qi;
 8 };
 9 
10 bool cmp(Node a, Node b){
11     return a.Pi / a.Qi > b.Pi / b.Qi;
12 }
13 
14 Node path[1010];
15 double dp[1010][15];
16 double deal(int n, int k){
17     memset(dp, 0, sizeof(dp));
18     dp[0][0] = 1;
19     double ret = 0;
20     for(int i = 1; i <= n; i++){
21         
22         for(int j = k; j >= 1; j--){
23             ret += dp[i-1][j] * path[i].Pi;
24             dp[i][j] += dp[i-1][j] * (1.0 - path[i].Pi - path[i].Qi);
25             dp[i][j] += dp[i-1][j-1] * path[i].Qi;
26         }
27         ret += dp[i-1][0] * path[i].Pi;
28         dp[i][0] = dp[i-1][0] * (1.0 - path[i].Pi - path[i].Qi); 
29     }
30     return ret;
31 }
32 
33 int main()
34 {
35     int T;
36     scanf("%d", &T);
37     for(int cas = 1; cas <= T; cas++){
38         int n, k;
39         scanf("%d %d", &n, &k);
40         for(int i = 1; i <= n; i++){
41             scanf("%lf %lf", &path[i].Pi, &path[i].Qi);
42         }
43         sort(path+1, path+n+1, cmp);
44         printf("Case %d: %.5lf\n", cas, deal(n, k));
45     } 
46     return 0;
47 }

 

 

 

posted @ 2013-11-06 21:19  logx  阅读(238)  评论(0编辑  收藏  举报