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


    题目大意:在一个树形迷宫中,以房间为节点。有n间房间,每间房间存在陷阱的概率为ki,存在出口的概率为ei,如果这两种情况都不存在(概率为pi),那么只能做出选择走向下一个房间(包括可能会走向上一个房间)。根节点为1,当遇到陷阱时必须返回到根节点1处重新开始,当遇到出口时,走出迷宫。问从开始到走出迷宫所做出选择次数的期望值。

    题目分析:定义状态dp(i)表示在节点 i 处直到走出迷宫的选择次数期望值。则状态转移方程为:

    dp(i)=ki*dp(1)+(1/m)*pi*∑(dp(son)+1)  (i为叶子节点)  <1>

    dp(i)=ki*dp(1)+(1/m)*pi*(dp(father)+1)+(1/m)*pi*∑(dp(son)+1)  (i为非叶子节点)  <2>

    将<2>整理一下,得到:

    dp(i)=ki*dp(1)+(1/m)*pi*dp(father)+(1/m)*pi*∑dp(son)+pi

    显然,dp(i)都与dp(1)有关,另dp(i)=A(i)*dp(1)+B(i)*dp(father)+C(i)  <3>

    将<3>带入∑dp(son),得到:

    (1-(pi/m)*∑A(son))dp(i)=(ki+(pi/m)∑A(son))*dp(1)+(pi/m)*dp(father)+(pi/m)*∑C(son)+pi

    显然,A(i),B(i),C(i)可得。

    dp(1)=C(1)/(1-A(1)) 即为答案。

    代码如下:

    # include<iostream>
    # include<cstdio>
    # include<cmath>
    # include<vector>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    
    const int N=10005;
    const int INF=100000;
    const double eps=1e-9;
    
    int n;
    double k[N];
    double e[N];
    double A[N],B[N],C[N];
    vector<int>G[N];
    
    bool dfs(int u,int fa)
    {
        int m=G[u].size();
        double temp=0;
        A[u]=k[u];
        B[u]=(1-k[u]-e[u])/m;
        C[u]=1-k[u]-e[u];
        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])*A[v]/m;
            C[u]+=(1-k[u]-e[u])*C[v]/m;
            temp+=(1-k[u]-e[u])*B[v]/m;
        }
        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,x,y,cas=0;
        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",&x,&y);
                G[x].push_back(y);
                G[y].push_back(x);
            }
            for(int i=1;i<=n;++i){
                scanf("%lf%lf",k+i,e+i);
                k[i]/=100;
                e[i]/=100;
            }
            printf("Case %d: ",++cas);
            if(dfs(1,-1)&&fabs(1-A[1])>eps)
                printf("%.6lf
    ",C[1]/(1-A[1]));
            else printf("impossible
    ");
        }
        return 0;
    }
    

      

  • 相关阅读:
    位记录——Windows 7已安装Sublime Text 3、cynwin、SublimeClang
    尺度空间(Scale space)理论
    D3DXMatrixMultiply 函数
    素数推断算法(高效率)
    去除win7 64位系统桌面图标小箭头
    Bag标签之中的一个行代码实行中文分词实例1
    7个最好的免费杀毒软件下载
    利用Excel批量高速发送电子邮件
    Hibernate Criterion
    IOS新手教程(二)-控制流
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/5325258.html
Copyright © 2020-2023  润新知