• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
dwtfukgv
博客园    首页    新随笔    联系   管理    订阅  订阅
HDU 3366 Passage (概率DP)

题意: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;
}

 

posted on 2016-07-26 23:00  dwtfukgv  阅读(214)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3