您的位置:首页 > 其它

toj 3086 Passage (不错)

2013-11-06 21:19 281 查看

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

#include <stdio.h>
#include <iostream>
#include <algorithm>
using namespace std;

struct Node{
double Pi, Qi;
};

bool cmp(Node a, Node b){
return a.Pi / a.Qi > b.Pi / b.Qi;
}

Node path[1010];
double dp[1010][15];
double deal(int n, int k){
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
double ret = 0;
for(int i = 1; i <= n; i++){

for(int j = k; j >= 1; j--){
ret += dp[i-1][j] * path[i].Pi;
dp[i][j] += dp[i-1][j] * (1.0 - path[i].Pi - path[i].Qi);
dp[i][j] += dp[i-1][j-1] * path[i].Qi;
}
ret += dp[i-1][0] * path[i].Pi;
dp[i][0] = dp[i-1][0] * (1.0 - path[i].Pi - path[i].Qi);
}
return ret;
}

int main()
{
int T;
scanf("%d", &T);
for(int cas = 1; cas <= T; cas++){
int n, k;
scanf("%d %d", &n, &k);
for(int i = 1; i <= n; i++){
scanf("%lf %lf", &path[i].Pi, &path[i].Qi);
}
sort(path+1, path+n+1, cmp);
printf("Case %d: %.5lf\n", cas, deal(n, k));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: