HDU 3366

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
題意:n條通道和m百萬元,每一條通道有三種情況,一種是直接出去,概率是p,還有一種是碰上士兵,給1萬塊再回去,概率是q,或者是死路,再回去,概率是1-p-q。問最終出去時最優可能性。

思路:概率dp,既然問最優可能性,肯定是最有可能跑出去的情況最好了,就算跑不出去也要少碰士兵,所以先按p/q從大到小排序,然後dp[i][j]代表在第i個通道,還有j萬元的時候能出去的概率。這個時候,能直接出去的話,就把最終結果加上dp[i][j]*p;如果碰上士兵就dp[i+1][j-1]+=dp[i][j]*q;如果是死路,就dp[i+1][j]+=dp[i][j]*(1-p-q);

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
double dp[1024][12];
struct node
{
    double p,q;
    bool operator <(const node &a)const
    {
        return p/q > a.p/a.q;
    }
}num[1024];
int main()
{
    int t,kase = 1;
    scanf("%d",&t);
    while(t--)
    {
        int m,n;
        scanf("%d%d",&n,&m);
        for(int i = 0;i < n;i++)
        {
            scanf("%lf%lf",&num[i].p,&num[i].q);
        }
        sort(num,num+n);
        double ans = 0.0;
        memset(dp,0,sizeof(dp));
        dp[0][m] = 1.0;
        for(int i = 0;i < n;i++)
        {
            for(int j = m;j >= 0;j--)
            {
                ans+=num[i].p*dp[i][j];
                if(j>=1)
                    dp[i+1][j-1] += dp[i][j]*num[i].q;
                dp[i+1][j] += dp[i][j]*(1-num[i].q-num[i].p);
            }
        }
        printf("Case %d: %.5lf\n",kase++,ans);
    }
    return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章