zoukankan      html  css  js  c++  java
  • hdu4035(概率dp)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4035

    题意:有n个房间,由n-1条隧道连通起来,实际上就形成了一棵树, 从结点1出发,开始走,在每个结点i都有3种可能:

    1.被杀死,回到结点1处(概率为ki)

    2.找到出口,走出迷宫 (概率为ei)

    3.和该点相连有m条边,随机走一条

    求:走出迷宫所要走的边数的期望值。

    分析:这题得有很强的递推能力才递推得出来吧,下面是网上的解释:

    设 E[i]表示在结点i处,要走出迷宫所要走的边数的期望。E[1]即为所求。
    
        叶子结点:
        E[i] = ki*E[1] + ei*0 + (1-ki-ei)*(E[father[i]] + 1);
             = ki*E[1] + (1-ki-ei)*E[father[i]] + (1-ki-ei);
    
        非叶子结点:(m为与结点相连的边数)
        E[i] = ki*E[1] + ei*0 + (1-ki-ei)/m*( E[father[i]]+1 + ∑( E[child[i]]+1 ) );
             = ki*E[1] + (1-ki-ei)/m*E[father[i]] + (1-ki-ei)/m*∑(E[child[i]]) + (1-ki-ei);
    
        设对每个结点:E[i] = Ai*E[1] + Bi*E[father[i]] + Ci;
    
        对于非叶子结点i,设j为i的孩子结点,则
        ∑(E[child[i]]) = ∑E[j]
                       = ∑(Aj*E[1] + Bj*E[father[j]] + Cj)
                       = ∑(Aj*E[1] + Bj*E[i] + Cj)
        带入上面的式子得
        (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;
    
        从叶子结点开始,直到算出 A1,B1,C1;
    
        E[1] = A1*E[1] + B1*0 + C1;
        所以
        E[1] = C1 / (1 - A1);
        若 A1趋近于1则无解...
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <cmath>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <cstdlib>
    #include <stack>
    #include <vector>
    #include <set>
    #include <map>
    #define LL long long
    #define mod 100000000
    #define inf 0x3f3f3f3f
    #define eps 1e-9
    #define N 100010
    #define FILL(a,b) (memset(a,b,sizeof(a)))
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    using namespace std;
    double A[N],B[N],C[N];
    double k[N],e[N];
    vector<int>g[N];
    bool dfs(int u,int fa)
    {
        int m=g[u].size();
        A[u]=k[u];
        B[u]=(1-k[u]-e[u])/m;
        C[u]=1-k[u]-e[u];
        double temp=0;
        for(int i=0;i<m;i++)
        {
            int v=g[u][i];
            if(v==fa)continue;
            if(!dfs(v,u))return false;
            A[u]+=(1-k[u]-e[u])/m*A[v];
            C[u]+=(1-k[u]-e[u])/m*C[v];
            temp+=(1-k[u]-e[u])/m*B[v];
        }
        if(fabs(1-temp)<eps)return false;
        A[u]/=(1-temp);
        B[u]/=(1-temp);
        C[u]/=(1-temp);
        return true;
    }
    int main()
    {
        int T,n,u,v,cas=1;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            for(int i=1;i<=n;i++)g[i].clear();
            for(int i=1;i<n;i++)
            {
                scanf("%d%d",&u,&v);
                g[u].push_back(v);
                g[v].push_back(u);
            }
            for(int i=1;i<=n;i++)
            {
                scanf("%lf%lf",&k[i],&e[i]);
                e[i]/=100;k[i]/=100;
            }
            printf("Case %d: ",cas++);
            if(dfs(1,-1)&&fabs(A[1]-1)>eps)
            {
                printf("%.6lf
    ",C[1]/(1-A[1]));
            }
            else puts("impossible");
        }
    }
    View Code
  • 相关阅读:
    mysql基础操作
    网页粒子背景
    将Myeclipse项目改成Eclipse项目
    mybatis入门配置和调试
    《增删改查返回问题》
    AES加密与解密(秘钥)
    svn下载代码cleanup失败解决办法
    maven中net.sf.json报错
    idea提交SVN时忽略某些文件或文件夹
    《面试常问到的知识点》
  • 原文地址:https://www.cnblogs.com/lienus/p/4264828.html
Copyright © 2011-2022 走看看