码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 4035 概率dp

时间:2015-04-09 23:16:05      阅读:91      评论:0      收藏:0      [点我收藏+]

标签:

太吊了

  1 /*
  2 HDU 4035
  3 
  4     dp求期望的题。
  5     题意:
  6     有n个房间,由n-1条隧道连通起来,实际上就形成了一棵树,
  7     从结点1出发,开始走,在每个结点i都有3种可能:
  8         1.被杀死,回到结点1处(概率为ki)
  9         2.找到出口,走出迷宫 (概率为ei)
 10         3.和该点相连有m条边,随机走一条
 11     求:走出迷宫所要走的边数的期望值。
 12 
 13     设 E[i]表示在结点i处,要走出迷宫所要走的边数的期望。E[1]即为所求。
 14 
 15     叶子结点:
 16     E[i] = ki*E[1] + ei*0 + (1-ki-ei)*(E[father[i]] + 1);
 17          = ki*E[1] + (1-ki-ei)*E[father[i]] + (1-ki-ei);
 18 
 19     非叶子结点:(m为与结点相连的边数)
 20     E[i] = ki*E[1] + ei*0 + (1-ki-ei)/m*( E[father[i]]+1 + ∑( E[child[i]]+1 ) );
 21          = ki*E[1] + (1-ki-ei)/m*E[father[i]] + (1-ki-ei)/m*∑(E[child[i]]) + (1-ki-ei);
 22 
 23     设对每个结点:E[i] = Ai*E[1] + Bi*E[father[i]] + Ci;
 24 
 25     对于非叶子结点i,设j为i的孩子结点,则
 26     ∑(E[child[i]]) = ∑E[j]
 27                    = ∑(Aj*E[1] + Bj*E[father[j]] + Cj)
 28                    = ∑(Aj*E[1] + Bj*E[i] + Cj)
 29     带入上面的式子得
 30     (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;
 31     由此可得
 32     Ai =        (ki+(1-ki-ei)/m*∑Aj)   / (1 - (1-ki-ei)/m*∑Bj);
 33     Bi =        (1-ki-ei)/m            / (1 - (1-ki-ei)/m*∑Bj);
 34     Ci = ( (1-ki-ei)+(1-ki-ei)/m*∑Cj ) / (1 - (1-ki-ei)/m*∑Bj);
 35 
 36     对于叶子结点
 37     Ai = ki;
 38     Bi = 1 - ki - ei;
 39     Ci = 1 - ki - ei;
 40 
 41     从叶子结点开始,直到算出 A1,B1,C1;
 42 
 43     E[1] = A1*E[1] + B1*0 + C1;
 44     所以
 45     E[1] = C1 / (1 - A1);
 46     若 A1趋近于1则无解...
 47 
 48 */
 49 #include<stdio.h>
 50 #include<string.h>
 51 #include<algorithm>
 52 #include<iostream>
 53 #include<math.h>
 54 #include<vector>
 55 using namespace std;
 56 const int MAXN=10010;
 57 const double eps=1e-9;//这里1e-8会WA。设为1e-9和1e-10可以
 58 double k[MAXN],e[MAXN];
 59 double A[MAXN],B[MAXN],C[MAXN];
 60 
 61 vector<int>vec[MAXN];//存树
 62 
 63 bool dfs(int t,int pre)//t的根结点是pre
 64 {
 65     int m=vec[t].size();//点t的度
 66     A[t]=k[t];
 67     B[t]=(1-k[t]-e[t])/m;
 68     C[t]=1-k[t]-e[t];
 69     double tmp=0;
 70     for(int i=0;i<m;i++)
 71     {
 72         int v=vec[t][i];
 73         if(v==pre)continue;
 74         if(!dfs(v,t))return false;
 75         A[t]+=(1-k[t]-e[t])/m*A[v];
 76         C[t]+=(1-k[t]-e[t])/m*C[v];
 77         tmp+=(1-k[t]-e[t])/m*B[v];
 78     }
 79     if(fabs(tmp-1)<eps)return false;
 80     A[t]/=(1-tmp);
 81     B[t]/=(1-tmp);
 82     C[t]/=(1-tmp);
 83     return true;
 84 }
 85 int main()
 86 {
 87    // freopen("in.txt","r",stdin);
 88    // freopen("out.txt","w",stdout);
 89     int T;
 90     int n;
 91     int u,v;
 92     int iCase=0;
 93     scanf("%d",&T);
 94     while(T--)
 95     {
 96         iCase++;
 97         scanf("%d",&n);
 98         for(int i=1;i<=n;i++)vec[i].clear();
 99         for(int i=1;i<n;i++)
100         {
101             scanf("%d%d",&u,&v);
102             vec[u].push_back(v);
103             vec[v].push_back(u);
104         }
105         for(int i=1;i<=n;i++)
106         {
107             scanf("%lf%lf",&k[i],&e[i]);
108             k[i]/=100;
109             e[i]/=100;
110         }
111         printf("Case %d: ",iCase);
112         if(dfs(1,-1)&&fabs(1-A[1])>eps)
113         {
114             printf("%.6lf\n",C[1]/(1-A[1]));
115         }
116         else printf("impossible\n");
117     }
118 }

 

hdu 4035 概率dp

标签:

原文地址:http://www.cnblogs.com/cnblogs321114287/p/4412341.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!