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\n",C[1]/(1-A[1]));
        else printf("impossible\n");
    }
    return 0;
}

  

posted @ 2016-03-27 11:41  20143605  阅读(479)  评论(0编辑  收藏  举报