HDU 3366 Passage (概率DP)

Passage

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


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百万dollars,每条路你逃跑的概率是p,遇到守卫的概率是q(这时你要给守卫1百万元然后退回城堡,否则你就挂了),还有1-p-q的概率走不通,这时你要退回城堡,退回城堡时可以再选择走之前没走过的路。假设你可以随意选择走哪条路,问在最优的策略下你逃出的概率是多少。

思路:什么是最优策略呢,那就是每次都走当前逃生几率最大的那条路,因此首先我们将所有路按照逃生率从大到小排序,根据上面“”每条路你逃跑的概率是p,遇到守卫的概率是q“”,可得对于每条路逃跑概率是p/(p+q)。那么此时走法便是从第一条路开始依次走到第n条。设dp(i,j)表示当前在第i条路,还剩j个钱,能够逃出的概率,最终答案就是dp(0,m),对每条路有三种情况:1.从这条路逃走了,这个概率就是p.  2.这条路上遇到了守卫,那么最终还能逃走的话就要满足两个条件——有钱,在接下来的路中能逃走,总概率便是q*dp(i+1,j-1).3.这条路走不通,那么要想最终逃跑的话也是要在接下来的路中能够逃走,总概率是(1-p-q)*dp(i+1,j),三者加和便是状态转移方程。
#include
#include
#include
#include
#include
#include
#include
using namespace std;

const int maxn = 1000 + 10;

struct node
{
    double p,q;
    void read(){
       scanf("%lf%lf",&p,&q);
    }
    bool operator < (const node &B) const{
       return p / (p + q) > B.p / (B.p + B.q);
    }
}pa[maxn];

double dp[1005][15];

int main()
{
    int T;
    scanf("%d",&T);
    int kase = 0;
    while(T--){
        int n,m;
        scanf("%d%d",&n,&m);
        for (int i = 0; i < n; i++)
            pa[i].read();

        sort(pa, pa + n);
        memset(dp, 0, sizeof(dp));
        for(int i = n - 1; i >= 0; i--){
            for(int j = 0; j <= m; j++){
                dp[i][j] = pa[i].p;
                if(i + 1 < n && j - 1 >= 0) dp[i][j] += dp[i + 1][j - 1] * pa[i].q;
                if(i + 1 < n) dp[i][j] += (1 - pa[i].p - pa[i].q) * dp[i + 1][j];
            }
        }
        printf("Case %d: %.5lf\n",++kase, dp[0][m]);

    }
}


你可能感兴趣的:(动态规划)