HDU 3366 Passage (概率DP)

101 篇文章 1 订阅

Passage

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 465    Accepted Submission(s): 218


Problem Description
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.
 

Input
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.
 

Output
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.
 

Sample Input
  
  
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
 

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

Source
 

Recommend

大体题意:
你陷入了一个城堡,有n个门可供选择,每个门逃生的概率是p[i],遇到士兵的概率是q[i],遇到士兵你必须交1百万,
逃不出去的概率的是1 - p[i] - q[i],你总共有M百万元,问最终逃生的概率是多少?
思路:
很明显概率DP,当时没有想出来= = !
用dp[i][j] 表示选择第i 个门时 你还有j 百万元。
注意,在选择门时 要优先选择逃生几率大的门,即 p[i]/ q[i]大的门,所以要给门排个序。
逃生的概率:
ans += dp[i][j] * p[i].p;
遇到士兵的概率:当然必须付的起一百万!
dp[i+1][j-1] += dp[i][j] * p[i].q;
逃不了的概率:
dp[i+1][j] += dp[i][j] * (1.0- p[i] - q[i]);
最后输出ans即可!
详细见代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 1000 + 10;
struct Node{
    double p,q;
    bool operator < (const Node & rhs)const {
        return p/q > rhs.p/rhs.q;
    }
}p[maxn];
double dp[maxn][15];
int main(){
    int T;
    scanf("%d",&T);
    int cnt = 0;
    while(T--){
        int n,m;
        scanf("%d %d",&n,&m);
        for (int i = 0; i < n; ++i){
            scanf("%lf %lf",&p[i].p,&p[i].q);
        }
        sort(p,p+n);
        memset(dp,0,sizeof dp);
        dp[0][m] = 1.0;
        double ans = 0.0;
        for (int i = 0; i < n; ++i){
            for (int j = m; j >= 0; --j){
                ans += dp[i][j] * p[i].p;
                dp[i+1][j] += dp[i][j]*(1.0-p[i].p-p[i].q);
                if (j-1 >= 0) dp[i+1][j-1] += dp[i][j]*p[i].q;
            }

        }
        printf("Case %d: %.5lf\n",++cnt,ans);

    }


    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值