zoukankan      html  css  js  c++  java
  • hdu4035 Maze (树上dp求期望)

     dp求期望的题。
        题意:
        有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);//因为是到达,i点跑出去的期望步数,所以逃出去的那个概率应该乘以0
             = 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则无解...
    上面这一问题,中发现E[1]消不去,然后就用算出A,B,C的方式来求解。
     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<iostream>
     5 #include<cmath>
     6 #include<vector>
     7 using namespace std;
     8 const int MAXN=10007;
     9 const double eps=1e-10;//这里1e-8会WA。设为1e-9和1e-10可以
    10 double k[MAXN],e[MAXN];
    11 double A[MAXN],B[MAXN],C[MAXN];
    12 
    13 int T,n,u,v,iCase;
    14 vector<int>vec[MAXN];//存树
    15 
    16 bool dfs(int t,int pre)//t的根结点是pre
    17 {
    18     int m=vec[t].size();//点t的度
    19     A[t]=k[t];
    20     B[t]=(1-k[t]-e[t])/m;
    21     C[t]=1-k[t]-e[t];
    22     double tmp=0;
    23     for(int i=0;i<m;i++)
    24     {
    25         int v=vec[t][i];
    26         if(v==pre)continue;
    27         if(!dfs(v,t))return false;
    28         A[t]+=(1-k[t]-e[t])/m*A[v];
    29         C[t]+=(1-k[t]-e[t])/m*C[v];
    30         tmp+=(1-k[t]-e[t])/m*B[v];
    31     }
    32     if(fabs(tmp-1)<eps)return false;
    33     A[t]/=(1-tmp);
    34     B[t]/=(1-tmp);
    35     C[t]/=(1-tmp);
    36     return true;
    37 }
    38 int main()
    39 {
    40     scanf("%d",&T);
    41     while(T--)
    42     {
    43         iCase++;
    44         scanf("%d",&n);
    45         for(int i=1;i<=n;i++)vec[i].clear();
    46         for(int i=1;i<n;i++)
    47         {
    48             scanf("%d%d",&u,&v);
    49             vec[u].push_back(v);
    50             vec[v].push_back(u);
    51         }
    52         for(int i=1;i<=n;i++)
    53         {
    54             scanf("%lf%lf",&k[i],&e[i]);
    55             k[i]/=100;
    56             e[i]/=100;
    57         }
    58         printf("Case %d: ",iCase);
    59         if(dfs(1,-1)&&fabs(1-A[1])>eps)
    60         {
    61             printf("%.6lf
    ",C[1]/(1-A[1]));
    62         }
    63         else printf("impossible
    ");
    64     }
    65 }
     
  • 相关阅读:
    【Spring】每个程序员都使用Spring(四)——Aop+自定义注解做日志拦截
    倪光南:保护科技人员知识产权是提升企业创新的关键(柳传志,杨元庆没有投入资金和技术,却占了大量股份,在全世界都非常少见)
    凡是能导到线上的都已经尝试过了,现在转化用户成本非常高,到了强者恒强的时代
    MIPS 指令集将在近期开源,RISC-V 阵营慌吗?
    QmlWinExtras
    用css解决Unigui在IE系列浏览器中字体变小的问题(设置UniServeModule的customcss属性)
    uni-app
    .net core consul grpc--系统服务RPC实现通信(一)
    系统间通信——RPC架构设计
    程序是由数据结构属于静态的部分和算法的调用为动态部分构成
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/7673939.html
Copyright © 2011-2022 走看看