zoukankan      html  css  js  c++  java
  • HDU 4035:Maze 概率DP求期望(有环)

    Maze

    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=4035

    题意:

    有N(2 ≤ N ≤ 10000)个房间和一堆双向边(不存在环),每个房间有ki和ei两个值,分别代表回到房间1和游戏结束的概率,求游戏结束时通过的边数的期望

    题解:

    一道很好很经典的求期望的题

    设E[i]为以i为起点,直到游戏结束所通过边数的期望,则E[1]即所求答案

    设fa代表父亲节点(由于不存在环,则图为一棵树,设1为根节点),∑ch代表所有孩子节点,size代表与这个房间直接相连的房间数,设X=1-ki-ei

    可以推导出 E[i]=ki*E[1]+X*(1/size*(E[fa]+1/size*∑E[ch])+1)---公式1

    设 E[i]=a[i]*E[1]+b[i]*E[fa]+c[i]

    则 ∑E[ch]=∑(a[ch]*E[1]+b[ch]*E[i]+c[ch])

    代入公式1可得 E[i]=( (ki+X/size*∑a[ch])*E[1]+X/size*∑E[fa]+X+X/size*∑(c[ch]) ) /(1-X/size*b[ch])

    对比可得

      a[i]=(ki+X/size*∑a[ch])/(1-X/size*b[ch])

      b[i]=X/size/(1-X/size*b[ch])

      c[i]=(X+X/size*c[ch])/(1-X/size*b[ch])

    E[1]=a[1]*E[1]+b[1]*E[fa]+c[1]=(a[1]*E[fa]+c[1])/(1-a[1])=c[1]/(1-a[1])

                 

    代码

    #include<stdio.h>
    #include<vector>
    #include<math.h>
    using namespace std;
    const int N=10005;
    const double eps=1e-9;
    vector<int>q[N];
    bool mark[N];
    int fa[N],out[N],que[N],head,tail;
    double k[N],e[N],A,B,C;
    void dfs(int x=1)
    {
      bool leaf=true;
      double p=1-k[x]-e[x];
      mark[x]=true;
      int m=q[x].size();
      double a=0.0,b=0.0,c=0.0;
      for(int i=0;i<q[x].size();++i)
      {
        fa[q[x][i]]=x;
        if(!mark[q[x][i]])
        {
          leaf=false;
          dfs(q[x][i]);
          a+=A,b+=B,c+=C;
        }
      }
      if(leaf)
      {
        A=k[x];
        B=C=p;
      }
      else
      {
        A=(k[x]+p/m*a)/(1-p/m*b);
        B=p/m/(1-p/m*b);
        C=(p+p/m*c)/(1-p/m*b);
      }
    }
    int main()
    {
      int T,n,x,y,leaf,w=0;
      scanf("%d",&T);
      while(T--)
      {
        scanf("%d",&n);
        for(int i=1;i<=n;++i)
        out[i]=0,mark[i]=false,q[i].clear();
        for(int i=1;i<n;++i)
        {
          scanf("%d%d",&x,&y);
          q[x].push_back(y);
          q[y].push_back(x);
        }
        for(int i=1;i<=n;++i)
        {
          scanf("%lf%lf",&k[i],&e[i]);
          k[i]/=100.0,e[i]/=100.0;
        }
        dfs();
        printf("Case %d: ",++w);
        if(fabs(1-A)<eps)printf("impossible ");
        else printf("%.6f ",C/(1-A));
      }
    }

      

  • 相关阅读:
    假期周进度报告02
    假期周进度报告01
    浪潮之巅阅读笔记6
    浪潮之巅阅读笔记5
    浪潮之巅阅读笔记4
    科技创新平台年报系统利益相关者分析
    浪潮之巅阅读笔记3
    浪潮之巅阅读笔记2
    浪潮之巅阅读笔记1
    Linux Redis 重启数据丢失解决方案,Linux重启后Redis数据丢失解决方
  • 原文地址:https://www.cnblogs.com/kiuhghcsc/p/5571295.html
Copyright © 2011-2022 走看看