hdu4035 概率DP求期望
Posted 文竹balala
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu4035 概率DP求期望相关的知识,希望对你有一定的参考价值。
题意:
有一个迷宫有n个房间,n-1条边,每个房间都有一定的概率掉进陷阱(概率为ki)或者逃出迷宫(概率为ei),在每个房间进入任何一个相邻的房间的概率是相等的,开始时在1号房间,每次掉进陷阱后会从1号房间从新开始,求逃出迷宫走的边的期望,如果不肯能则输出impossible。
分析:
这是一道概率dp,但是一直想不出来状态和状态转移方程,还是看了kuangbin大神的题解,发现二维状态行不通,因为可能会重复的走下去,这道题的隐藏条件应该是没有环,然后就形成了一棵树,这里引用他的思路,要我自己肯定想不出来,算是加深印象了。
就可以联想到从叶子节点向1号递推,用E[i]表示从i节点逃出迷宫的期望,则E[1]就是所求,和前边做的题很像,就是一个从最终状态到开始状态。
对于叶子节点:
E[i] = ki*E[1] + ei*0 + (1-ki-ei)*(E[father[i]] + 1])
对于非叶子节点
E[i] = ki*E[1] + ei*0 + (1-ki-ei)/m*(E[father[i]] + 1]) + (1-ki-ei)/m*(∑(E[child[i]] + 1))
设对每个结点:E[i] = Ai*E[1] + Bi*E[father[i]] + Ci;
设j为i的孩子节点 ∑(E[child[i]] = ∑(E[j]) = ∑(Aj*E[1] + Bj*E[i] + C[j])
带入上式得
(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;
所以从1号开始进行一个dfs即可
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cmath>
#include <algorithm>
typedef long long ll;
using namespace std;
const int maxn = 10000 + 5;
const double eps = 1e-9;
vector <int> g[maxn];
double A[maxn], B[maxn], C[maxn], E[maxn];
double kill[maxn], exi[maxn];
bool dfs(int u, int pre)
int m = g[u].size();
A[u] = kill[u];
B[u] = (1 - kill[u] - exi[u]) / m;
C[u] = 1 - kill[u] - exi[u];
double tmp = 0;
for (int i = 0; i < m; i++)
int v = g[u][i];
if (v == pre)continue;
if (!dfs(v, u))return false;
A[u] += (1-kill[u]-exi[u])/m*A[v];
C[u] += (1-kill[u]-exi[u])/m*C[v];
tmp += (1-kill[u]-exi[u])/m*B[v];
if (fabs(1 - tmp) < eps) return false;
A[u] /= (1-tmp);
B[u] /= (1-tmp);
C[u] /= (1-tmp);
return true;
int main()
//freopen("input.txt", "r", stdin);
int t;
cin >> t;
int kcase = 0;
while(t--)
int n;
cin >> n;
for (int i = 1; i <= n; i++)
g[i].clear();
E[i] = 0.0;
for (int i = 0; i < n-1; i++)
int x, y;
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", kill+i, exi+i);
kill[i] /= 100;
exi[i] /= 100;
if (dfs(1, -1) && fabs(1-A[1]) > eps)
printf("Case %d: %.6f\\n", ++kcase, C[1]/(1-A[1]));
else printf("Case %d: impossible\\n", ++kcase);
return 0;
以上是关于hdu4035 概率DP求期望的主要内容,如果未能解决你的问题,请参考以下文章