题意:有一个树形的迷宫,有N个房间(标号为1~N)以及N-1条通道将它们连通,一开始在1号房间,每进入一个房间i,有k[i]的概率被陷阱杀死回到房间1,有s[i]的概率找到出口逃离迷宫,如果没有找到出口也没有被杀,那么就在与该房间相连的通道中等概率随机选一条走,求逃离迷宫所需要走的通道数的期望值(如果不能逃离输出impossible)。

解法:这道题非常锻炼处理式子的能力,非常值得一做!讲一下推理过程:

首先容易想到状态设计:dp[i]代表从i点出发直到离开迷宫的期望步数,那么写出状态转移方程:

dp[x]=k[x]*dp[1] + (1-k[x]-s[x]) * (dp[fa]+1 sigma(dp[son]+1) ) /du[x] ;

观察这个式子,dp[x]与4个部分有关:dp[1]  ,dp[fa] , dp[son] , 常数项C

令人沮丧的是dp与fa和son都有关系意味着有环,那么就得使用高斯消元解决。但是注意到数据量10000高斯消元显然超时。我们只能另寻他法。

我们要尽量利用树的特性,儿子与父亲有密切关系。注意到叶子结点的dp方程是没有儿子项的,那么能不能利用这个把环消掉?如果能利用叶子一层层往上代的话也许能消去全部的儿子项!!

这样的话我们尝试把所有的方程写成  dp[i]=Ai*dp[1] + Bi*dp[fa] + Ci   (没有儿子项)

这样的话  叶子dp[son]=k[son]*dp[1] + (1-k[x]-s[x])*(dp[fa]+1) 的 Ai=k[i]  Bi=1-k[i]-s[i]  Ci=1-k[i]-s[i]

我们把叶子写出 dp[son]=Ason*dp[1] + Bson*dp[fa] + Cson  带入到他的父亲方程(注意此时dp[son]=Ason*dp[1] + Bson*dp[x] + Cson  即fa变成了x)中得到

du[x]dp[x] - (1-k[i]-s[i])(sigmaBson)dp[x] = (du[x]*k[x]+(1-k[x]-s[x])(sigmaAson)) *dp[1]  +  (1-k[x]-s[x])*dp[fa]  +  (1-k[x]-s[x])*du[x] + (1-k[x]-s[x])*(sigmaCson)

虽然这个式子很长,但是可以看得出 Ax  Bx  Cx

那么到这里也就意味着我们能从叶子一直往上推我们就能得到每个点的Ax Bx Cx。那么一直到根节点1的时候就能得到答案,dp[1]=C1/(1-A1)。

要注意也就是A1=1的时候无解。且这题卡精度了eps要1e-9。

代码如下。但是建议大家自己完完整整推一次式子然后自己写程序完成。

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+;
const double eps=1e-;
int n,m;
double k[N],s[N];
vector<int> G[N]; double A[N],B[N],C[N];
void dfs(int x,int fa) {
if (G[x].size()== && x!=) {
A[x]=k[x]; B[x]=-k[x]-s[x]; C[x]=-k[x]-s[x];
return;
}
double du=G[x].size(),go=-k[x]-s[x];
A[x]=du*k[x]; B[x]=go; C[x]=go*du;
double t=G[x].size();
for (int i=;i<G[x].size();i++) {
int y=G[x][i];
if (y==fa) continue;
dfs(y,x);
A[x]+=go*A[y];
C[x]+=go*C[y];
t-=go*B[y];
}
A[x]/=t; B[x]/=t; C[x]/=t;
} int main()
{
int T,cas=; cin>>T;
while (T--) {
scanf("%d",&n);
for (int i=;i<=n;i++) G[i].clear();
for (int i=;i<n;i++) {
int x,y; scanf("%d%d",&x,&y);
G[x].push_back(y);
G[y].push_back(x);
}
for (int i=;i<=n;i++) scanf("%lf%lf",&k[i],&s[i]);
for (int i=;i<=n;i++) k[i]/=100.0,s[i]/=100.0; memset(A,,sizeof(A));
memset(B,,sizeof(B));
memset(C,,sizeof(C));
dfs(,);
if (fabs(A[]-1.0)<eps) printf("Case %d: impossible\n",++cas);
else printf("Case %d: %.6lf\n",++cas,C[]/(-A[]));
}
return ;
}

HDU4035 Maze 期望DP+树形DP(好题)的更多相关文章

  1. 选课 ( dp 树形dp 动态规划 树规)

    和某篇随笔重了?!!?!?!?!?!?不管了留着吧 题目: 在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之 ...

  2. HDU4035 Maze(期望DP)

    题意 抄袭自https://www.cnblogs.com/Paul-Guderian/p/7624039.html 有n个房间,由n-1条隧道连通起来,形成一棵树,从结点1出发,开始走,在每个结点i ...

  3. luogu P4284 [SHOI2014]概率充电器 期望 概率 树形dp

    LINK:概率充电器 大概是一个比较水的题目 不过有一些坑点. 根据期望的线性性 可以直接计算每个元件的期望 累和即为答案. 考虑统计每一个元件的概率的话 那么对其有贡献就是儿子 父亲 以及自己. 自 ...

  4. 加分二叉树 vijos1991 NOIP2003第三题 区间DP/树形DP/记忆化搜索

    描述 设一个n个节点的二叉树tree的中序遍历为(l,2,3,-,n),其中数字1,2,3,-,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数为di,tree及它的每个子树都有一 ...

  5. HDU 4035 Maze 概率dp,树形dp 难度:2

    http://acm.hdu.edu.cn/showproblem.php?pid=4035 求步数期望,设E[i]为在编号为i的节点时还需要走的步数,father为dfs树中该节点的父节点,son为 ...

  6. ZROJ#398. 【18提高7】随机游走(期望dp 树形dp)

    题意 [题目链接]版权原因就不发了.. 给出一棵树,求出任意两点之间期望距离的最大值 Sol 比较清真的一道题吧.. 设\(f[x]\)表示从\(x\)走到\(x\)的父亲的期望步数 \(g[x]\) ...

  7. BZOJ.3566.[SHOI2014]概率充电器(概率DP 树形DP)

    BZOJ 洛谷 这里写的不错,虽然基本还是自己看转移... 每个点的贡献都是\(1\),所以直接求每个点通电的概率\(F_i\),答案就是\(\sum F_i\). 把\(F_x\)分成:父节点通电给 ...

  8. BZOJ1791[Ioi2008]Island 岛屿 ——基环森林直径和+单调队列优化DP+树形DP

    题目描述 你将要游览一个有N个岛屿的公园.从每一个岛i出发,只建造一座桥.桥的长度以Li表示.公园内总共有N座桥.尽管每座桥由一个岛连到另一个岛,但每座桥均可以双向行走.同时,每一对这样的岛屿,都有一 ...

  9. 树形DP和状压DP和背包DP

    树形DP和状压DP和背包DP 树形\(DP\)和状压\(DP\)虽然在\(NOIp\)中考的不多,但是仍然是一个比较常用的算法,因此学好这两个\(DP\)也是很重要的.而背包\(DP\)虽然以前考的次 ...

随机推荐

  1. Python---基础---list(列表)

    2019-05-20 一. # append()  向列表末尾追加新元素   返回值Nonelist1 = [1,2,3,4,5]print(id(list1))list1.append(6)prin ...

  2. OSI参考模型与TCP/IP参考模型与TCP/IP协议栈

    原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11484126.html OSI参考模型与TCP/IP参考模型与TCP/IP协议栈 TCP/IP分层模型 ...

  3. No module named flask 导包失败,Python3重新安装Flask模块

    在部署环境过程中,通过pip install -r requirements.txt安装包,结果启动项目时总是报错,显示没有flask模块,通过pip install flask还是不行,于是下载fl ...

  4. CMD批处理查看当前路径

    1.直接在CMD窗口查看 echo %cd% 2.建立批处理文件 @echo offecho 当前盘符:%~d0echo 当前盘符和路径:%~dp0echo 当前批处理全路径:%~f0echo 当前盘 ...

  5. MaxCompute Studio 使用入门

    MaxCompute Studio 是MaxCompute 平台提供的安装在开发者客户端的大数据集成开发环境工具,是一套基于流行的集成开发平台 IntelliJ IDEA 的开发插件,可以帮助您方便地 ...

  6. oppo面试题

    1.synchronized和Lock有什么区别?哪个可重入?哪个效率高? synchronized和Lock都用于线程同步的场景中. synchronized是jdk的关键字,用来构造同步代码块或者 ...

  7. php随机数原理

    php随机数原理: 系统自动生成一个随机数种子(mt_srand函数可以自己生成种子),mt_rand先判断是否有生成种子,没有就自动生成一个,然后根据种子生成随机数. 生成10000-99999随机 ...

  8. [转]Html.DropDownList()的用法 ( Asp.Net MVC)

    Html.DropDownList()赋默认值: 页面代码如下: <% List<SelectListItem> list = new List<SelectListItem& ...

  9. char* 和 cha[]

    char* s1 = "hello";//字符串常量 s是一个保存了字符串首地址的指针变量,同时也是字符串的名字,s的内容是第一个字符的地址,当s指向常量字符串时候,内容不能改变( ...

  10. JavaScript原型和闭包学习笔记

    在这里先和大家推荐一个博客,这博客的<深入理解javascript原型和闭包(完结)>系列,看了比较多的视频和书本,这个博客讲得很耐人寻味. 深入理解javascript原型和闭包(完结) ...