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

 //#pragma comment(linker,"/STACK:102400000,102400000")
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <vector>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define INF 1e8
#define inf (-((LL)1<<40))
#define lson k<<1, L, mid
#define rson k<<1|1, mid+1, R
#define mem0(a) memset(a,0,sizeof(a))
#define mem1(a) memset(a,-1,sizeof(a))
#define mem(a, b) memset(a, b, sizeof(a))
#define FOPENIN(IN) freopen(IN, "r", stdin)
#define FOPENOUT(OUT) freopen(OUT, "w", stdout)
template<class T> T CMP_MIN(T a, T b) { return a < b; }
template<class T> T CMP_MAX(T a, T b) { return a > b; }
template<class T> T MAX(T a, T b) { return a > b ? a : b; }
template<class T> T MIN(T a, T b) { return a < b ? a : b; }
template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; } //typedef __int64 LL;
//typedef long long LL;
const int MAXN = ;
const int MAXM = ;
const double eps = 1e-;
//const LL MOD = 1000000007; int T, N;
vector<int>v[MAXN];
double k[MAXN], e[MAXN];
double A[MAXN], B[MAXN], C[MAXN]; void init()
{
int U, V;
scanf("%d", &N);
for(int i=;i<=N;i++) v[i].clear();
for(int i=;i<N-;i++)
{
scanf("%d %d", &U, &V);
v[U].push_back(V);
v[V].push_back(U);
}
for(int i=;i<=N;i++)
{
scanf("%d %d", &U, &V);
k[i] = (double)U / 100.0;
e[i] = (double)V / 100.0;
}
} bool DFS(int x, int fa)
{
A[x] = k[x];
B[x] = ( - k[x] - e[x]) / v[x].size();
C[x] = - k[x] - e[x];
if(v[x].size() == && x != fa)
return true;
double temp = ;
for(int i = ; i < v[x].size() ; i ++ )
{
int y = v[x][i];
if(y == fa) continue;
if(!DFS(y, x)) return false;
A[x] += A[y] * B[x];
C[x] += C[y] * B[x];
temp += B[y] * B[x];
}
if(fabs(temp - 1.0) < eps) return false;
A[x] = A[x] / ( - temp);
B[x] = B[x] / ( - temp);
C[x] = C[x] / ( - temp);
return true;
} int main()
{
//FOPENIN("in.txt");
scanf("%d", &T);
for(int t = ; t <= T; t ++ )
{
init();
if( DFS(, ) && fabs(A[] - 1.0) > eps )
{
printf("Case %d: %lf\n", t, C[] / ( - A[]));
}
else
{
printf("Case %d: impossible\n", t);
}
}
}

HDU 4035Maze(概率DP)的更多相关文章

  1. HDU 4599 概率DP

    先推出F(n)的公式: 设dp[i]为已经投出连续i个相同的点数平均还要都多少次才能到达目标状态. 则有递推式dp[i] = 1/6*(1+dp[i+1]) + 5/6*(1+dp[1]).考虑当前这 ...

  2. HDU 5001 概率DP || 记忆化搜索

    2014 ACM/ICPC Asia Regional Anshan Online 给N个点,M条边组成的图,每一步能够从一个点走到相邻任一点,概率同样,问D步后没走到过每一个点的概率 概率DP  測 ...

  3. hdu 3853 概率dp

    题意:在一个R*C的迷宫里,一个人在最左上角,出口在右下角,在每个格子上,该人有几率向下,向右或者不动,求到出口的期望 现在对概率dp有了更清楚的认识了 设dp[i][j]表示(i,j)到(R,C)需 ...

  4. HDU 4815 概率dp,背包

    Little Tiger vs. Deep Monkey Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K ( ...

  5. hdu 4050(概率dp)

    算是挺简单的一道概率dp了,如果做了前面的聪聪于可可的话,这题不需要什么预处理,直接概率dp就行了... #include <stdio.h> #include <stdlib.h& ...

  6. HDU 4405 (概率DP)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4405 题目大意:飞行棋.如果格子不是飞行点,扔骰子前进.否则直接飞到目标点.每个格子是唯一的飞行起点 ...

  7. hdu 4336 概率dp + 状压

    hdu 4336 小吃包装袋里面有随机赠送一些有趣的卡片,如今你想收集齐 N 张卡片.每张卡片在食品包装袋里出现的概率是p[i] ( Σp[i] <= 1 ), 问你收集全部卡片所需购买的食品数 ...

  8. hdu 4576(概率dp+滚动数组)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4576 思路:由于每次从某一位置到达另一位置的概率为0.5,因此我们用dp[i][j]表示第i次操作落在 ...

  9. hdu 5001 概率DP 图上的DP

    http://acm.hdu.edu.cn/showproblem.php?pid=5001 当时一看是图上的就跪了 不敢写,也没退出来DP方程 感觉区域赛的题  一则有一个点难以想到 二则就是编码有 ...

  10. hdu 3853LOOPS (概率DP)

    LOOPS Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 125536/65536 K (Java/Others) Total Su ...

随机推荐

  1. Kafka源码中的Producer Record定义

    1.ProducerRecord 含义: 发送给Kafka Broker的key/value 值对 2.内部数据结构: -- Topic (名字) -- PartitionID ( 可选) -- Ke ...

  2. Codeforces 505 A Mr. Kitayuta's Gift【暴力】

    题意:给出一个字符串,可以向该字符串的任意位置插入一个字母使其变成回文串 因为字符串的长度小于10,枚举插入的字母,和要插入的位置,再判断是否已经满足回文串 #include<iostream& ...

  3. HDU 5319 Painter (模拟)

    题意: 一个画家画出一张,有3种颜色的笔,R.G.B.R看成'\',B看成'/',G看成这两种的重叠(即叉形).给的是一个矩阵,矩阵中只有4种符号,除了3种颜色还有'.',代表没有涂色.问最小耗费多少 ...

  4. 【英语】Bingo口语笔记(33) - 面部器官系列

    to play by ear Play就是玩的意思.可是,play by ear的意思并不是“玩耳朵”.这个词汇的来源和音乐有关系.它原来指的是那些会弹钢琴或某种乐器,但是却不会看五线谱的人.每当他们 ...

  5. 实验室 Linux 集群的管理常用命令

    实验室有一个Linux集群,本文做一下记录. SSH相关命令 通过SSH登录集群中的其他机器上的操作系统(或虚拟机中的操作系统).操作系统之间已经设置免密码登录. 1. 无选项参数运行 SSH 通常使 ...

  6. C++调试 输出数组内容和数组名

    #include <cstdio> using namespace std; //函数定义 #define printArr(arr,n,format) \ printf("%s ...

  7. 如何用HTML5+PhoneGap写个Path项目

    最近Path这个应用很火爆,网上也出现了不少仿Path菜单的项目.即使在原生APP里边,Path的效果也是非常赞的.我突然想,Web APP是不是也能做出类似Path那样的效果呢?于是就有了OPath ...

  8. hibernate建表一对多 一的一方控制多的方

    级联操作,操作class对象的时候 级联操作 student Classes.java文件 package cn.itcast.hiberate.sh.domain; import java.util ...

  9. 《C++ primer》--第1,2章小结

    来源:http://blog.csdn.net/wangqiulin123456/article/details/8483853 1.变量初始化:      定义变量时,应该给变量赋初始值,除非确定将 ...

  10. AFNetWorking 使用记录

    1.从一个URL  GET数据 方法1: NSURL * url = [NSURL URLWithString:@"http://www.weather.com.cn/data/sk/101 ...