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

HDU 4035Maze(概率DP)

时间:2014-08-03 15:05:05      阅读:251      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   io   for   art   

HDU 4035   Maze

体会到了状态转移,化简方程的重要性

题解转自http://blog.csdn.net/morgan_xww/article/details/6776947

 

 

/**
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);
= 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则无解...
**/

  1 //#pragma comment(linker,"/STACK:102400000,102400000")
  2 #include <map>
  3 #include <set>
  4 #include <stack>
  5 #include <queue>
  6 #include <cmath>
  7 #include <ctime>
  8 #include <vector>
  9 #include <cstdio>
 10 #include <cctype>
 11 #include <cstring>
 12 #include <cstdlib>
 13 #include <iostream>
 14 #include <algorithm>
 15 using namespace std;
 16 #define INF 1e8
 17 #define inf (-((LL)1<<40))
 18 #define lson k<<1, L, mid
 19 #define rson k<<1|1, mid+1, R
 20 #define mem0(a) memset(a,0,sizeof(a))
 21 #define mem1(a) memset(a,-1,sizeof(a))
 22 #define mem(a, b) memset(a, b, sizeof(a))
 23 #define FOPENIN(IN) freopen(IN, "r", stdin)
 24 #define FOPENOUT(OUT) freopen(OUT, "w", stdout)
 25 template<class T> T CMP_MIN(T a, T b) { return a < b; }
 26 template<class T> T CMP_MAX(T a, T b) { return a > b; }
 27 template<class T> T MAX(T a, T b) { return a > b ? a : b; }
 28 template<class T> T MIN(T a, T b) { return a < b ? a : b; }
 29 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
 30 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b;    }
 31 
 32 //typedef __int64 LL;
 33 //typedef long long LL;
 34 const int MAXN = 10005;
 35 const int MAXM = 100005;
 36 const double eps = 1e-10;
 37 //const LL MOD = 1000000007;
 38 
 39 int T, N;
 40 vector<int>v[MAXN];
 41 double k[MAXN], e[MAXN];
 42 double A[MAXN], B[MAXN], C[MAXN];
 43 
 44 
 45 void init()
 46 {
 47     int U, V;
 48     scanf("%d", &N);
 49     for(int i=0;i<=N;i++) v[i].clear();
 50     for(int i=0;i<N-1;i++)
 51     {
 52         scanf("%d %d", &U, &V);
 53         v[U].push_back(V);
 54         v[V].push_back(U);
 55     }
 56     for(int i=1;i<=N;i++)
 57     {
 58         scanf("%d %d", &U, &V);
 59         k[i] = (double)U / 100.0;
 60         e[i] = (double)V / 100.0;
 61     }
 62 }
 63 
 64 bool DFS(int x, int fa)
 65 {
 66     A[x] = k[x];
 67     B[x] = (1 - k[x] - e[x]) / v[x].size();
 68     C[x] = 1 - k[x] - e[x];
 69     if(v[x].size() == 1 && x != fa)
 70         return true;
 71     double temp = 0;
 72     for(int i = 0; i < v[x].size() ; i ++ )
 73     {
 74         int y = v[x][i];
 75         if(y == fa) continue;
 76         if(!DFS(y, x)) return false;
 77         A[x] += A[y] * B[x];
 78         C[x] += C[y] * B[x];
 79         temp += B[y] * B[x];
 80     }
 81     if(fabs(temp - 1.0) < eps) return false;
 82     A[x] = A[x] / (1 - temp);
 83     B[x] = B[x] / (1 - temp);
 84     C[x] = C[x] / (1 - temp);
 85     return true;
 86 }
 87 
 88 int main()
 89 {
 90     //FOPENIN("in.txt");
 91     scanf("%d", &T);
 92     for(int t = 1; t <= T; t ++ )
 93     {
 94         init();
 95         if( DFS(1, 1) && fabs(A[1] - 1.0) > eps )
 96         {
 97             printf("Case %d: %lf\n", t, C[1] / (1 - A[1]));
 98         }
 99         else
100         {
101             printf("Case %d: impossible\n", t);
102         }
103     }
104 }

 

HDU 4035Maze(概率DP),布布扣,bubuko.com

HDU 4035Maze(概率DP)

标签:style   blog   http   color   os   io   for   art   

原文地址:http://www.cnblogs.com/gj-Acit/p/3888328.html

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