hdu4035 概率DP求期望

Posted 文竹balala

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu4035 概率DP求期望相关的知识,希望对你有一定的参考价值。

题意:

有一个迷宫有n个房间,n-1条边,每个房间都有一定的概率掉进陷阱(概率为ki)或者逃出迷宫(概率为ei),在每个房间进入任何一个相邻的房间的概率是相等的,开始时在1号房间,每次掉进陷阱后会从1号房间从新开始,求逃出迷宫走的边的期望,如果不肯能则输出impossible。

分析:

这是一道概率dp,但是一直想不出来状态和状态转移方程,还是看了kuangbin大神的题解,发现二维状态行不通,因为可能会重复的走下去,这道题的隐藏条件应该是没有环,然后就形成了一棵树,这里引用他的思路,要我自己肯定想不出来,算是加深印象了。

就可以联想到从叶子节点向1号递推,用E[i]表示从i节点逃出迷宫的期望,则E[1]就是所求,和前边做的题很像,就是一个从最终状态到开始状态。

对于叶子节点:

E[i]  = ki*E[1] +  ei*0 + (1-ki-ei)*(E[father[i]] + 1]) 

对于非叶子节点

E[i] = ki*E[1] + ei*0 + (1-ki-ei)/m*(E[father[i]] + 1]) + (1-ki-ei)/m*((E[child[i]] + 1))

设对每个结点:E[i] = Ai*E[1] + Bi*E[father[i]] + Ci;

j为i的孩子节点 (E[child[i]] = (E[j]) = (Aj*E[1] + Bj*E[i] + C[j])

带入上式得

(1 - (1-ki-ei)/m*∑Bj)*E[i] = (ki+(1-ki-ei)/m*∑Aj)*E[1] + (1-ki-ei)/m*E[father[i]] + (1-ki-ei) + (1-ki-ei)/m*∑Cj; 

Ai = (ki+(1-ki-ei)/m*∑Aj) / (1 - (1-ki-ei)/m*∑Bj)

Bi = (1-ki-ei)/m / (1 - (1-ki-ei)/m*∑Bj);

Ci = ( (1-ki-ei)+(1-ki-ei)/m*∑Cj ) / (1 - (1-ki-ei)/m*∑Bj);

对于叶子结点

Ai = ki; 

Bi = 1 - ki - ei;

Ci = 1 - ki - ei; 

  所以从1号开始进行一个dfs即可



#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cmath>
#include <algorithm>
typedef long long ll;
using namespace std;

const int maxn = 10000 + 5;
const double eps = 1e-9;
vector <int> g[maxn];

double A[maxn], B[maxn], C[maxn], E[maxn];
double kill[maxn], exi[maxn];
bool dfs(int u, int pre)

    int m = g[u].size();
    A[u] = kill[u];
    B[u] = (1 - kill[u] - exi[u]) / m;
    C[u] = 1 - kill[u] - exi[u];
    double tmp = 0;
    for (int i = 0; i < m; i++)
    
        int v = g[u][i];
        if (v == pre)continue;
        if (!dfs(v, u))return false;
        A[u] += (1-kill[u]-exi[u])/m*A[v];
        C[u] += (1-kill[u]-exi[u])/m*C[v];
        tmp += (1-kill[u]-exi[u])/m*B[v];
    
    if (fabs(1 - tmp) < eps) return false;
    A[u] /= (1-tmp);
    B[u] /= (1-tmp);
    C[u] /= (1-tmp);
    return true;




int main() 

    //freopen("input.txt", "r", stdin);
    int t;
    cin >> t;
    int kcase = 0;
    while(t--)
    
        int n;
        cin >> n;
        for (int i = 1; i <= n; i++)
        
            g[i].clear();
            E[i] = 0.0;
        
        for (int i = 0; i < n-1; i++)
        
            int x, y;
            scanf("%d%d", &x, &y);
            g[x].push_back(y);
            g[y].push_back(x);
        
        for (int i = 1; i <= n; i++)
        
            scanf("%lf%lf", kill+i, exi+i);
            kill[i] /= 100;
            exi[i] /= 100;

        
        if (dfs(1, -1) && fabs(1-A[1]) > eps)
        
            printf("Case %d: %.6f\\n", ++kcase, C[1]/(1-A[1]));
        
        else printf("Case %d: impossible\\n", ++kcase);

    
    return 0;




以上是关于hdu4035 概率DP求期望的主要内容,如果未能解决你的问题,请参考以下文章

HDU-4035 Maze (概率DP求期望)

HDU 4035:Maze 概率DP求期望(有环)

hdu 4035 Maze

HDU4035 Maze(期望DP)

[经典好题]HDU4035 Maze 期望树形DP

[hdu4035] Maze概率dp 数学期望