题意:T组测试数据,一个人困在了城堡中,有n个通道,m百万money ,每个通道能直接逃出去的概率为 P[i] ,遇到士兵的概率为 q[i],
遇到士兵得给1百万money,否则会被杀掉,还有 1-p[i]-q[i] 的概率走不通,要回头。问在可以选择的情况下,逃出去的概率是多少?
析:这个题很明显是概率DP么,就是不会。。。。在比赛时,读完题,直接放弃。。。。。
最后还是问的学长,是这样的,d[i][j],表示走第 i 个管道时,还剩 j 百万,那么怎么状态方程怎么转呢?
第一种情况:走了一个死胡同,走不通一,再走回来,那么d[i+1][j] = d[i][j] - (1-p[i]-q[i]);
第二种情况:碰到士兵了,交钱呗,d[i+1][j-1] = d[i][j] * q[i];
第三种情况:出去了,ans += d[i][j] * p[i];
那么剩下的就很简单了?no,如果这么写,第二组样例不过,因为有一个优先的问题,很明显是越早出去越好了,所以先要排个序,
规则是p/q大优先。现在剩下的就很简单了。
代码如下:
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <string>
#include <algorithm>
#include <vector>
#include <map>
using namespace std ;
typedef long long LL;
const int maxn = 1e3 + 5;
const int INF = 0x3f3f3f3f;
struct node{
    double p, q;
    bool operator < (const node &pq)  const{
        return p/q > pq.p/pq.q;
    }
};
double d[maxn][12];
node a[maxn];
int main(){
    int n, m, T;  cin >> T;
    for(int kase = 1; kase <= T; ++kase){
        cin >> n >> m;
        for(int i = 1; i <= n; ++i)
            cin >> a[i].p >> a[i].q;
        memset(d, 0, sizeof(d));
        d[1][m] = 1;
        sort(a+1, a+n+1);
        double ans = 0;
        for(int i = 1; i <= n; ++i){
            for(int j = m; j >= 0; --j){
                d[i+1][j] += d[i][j] * (1-a[i].p-a[i].q);
                d[i+1][j-1] += d[i][j] * a[i].q;
                ans += d[i][j] * a[i].p;
            }
        }
        printf("Case %d: %.5lf\n", kase, ans);
    }
    return 0;
}
 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号