这是一道告诉我概率没有想象中那么难的题.....

首先,用期望的线性性质,那么答案为所有点有电的概率和

发现一个点的有电的概率来源形成了一个"或"关系,在概率中,这并不好计算...(其实是可以算的,只不过式子要复杂点...)

考虑反面,一个点没电的概率来源是一个“与”关系,比较好计算

举个荔枝,有$A, B, C$三个变量,$A, B, C$分别有$0.5, 0.3, 0.2$的概率为$1$

问$A | B | C$为$1$的概率?

如果,我们从正面考虑,那么答案为$0.5 + (1 - 0.5) * 0.3 + (1 - 0.5 - (1 - 0.5) * 0.3) * 0.2 = 0.72$

但是,如果从反面考虑,那么答案为$1 - (1 - 0.2)(1 - 0.3)(1 - 0.5) = 0.72$

从这个荔枝可以看出,概率中“或”很难算,“与”比较好算(其实求解$| = !\&!$)

那么,考虑一个点没电,大体上分为子树不给电和父亲不给电两种情况

分别来考虑:

记$i$自己用爱发电的概率为$e_i$,边$(u, v)$用爱发电的概率为$e(u, v)$

设子树内不给$u$充电的概率为$f[u]$,那么$f[u] = (1 - e_i) * \prod_{v \in son_u} f[v] + (1 - f[v]) * (1 - e(u, v))$

再来考虑父亲不给电

设父亲不给$u$充电的为$g[u]$,那么有$g[u] = g[fa] + (1 - g[fa])(1 - e(u, fa))$

那么,求解$g[fa]$就成了一个问题,如果我们在$O(n ^2 )$的时间内求出所有的$g[fa]$,那么我们就能在$O(n ^ 2)$求出所有的$f$

在$O(n ^ 2)$的时间内求出$g[fa]$,自然是不难的,发现这是一个以$fa$为根的$dp$

对于一个节点,$f[u] *g[u]$就是答案

进一步分析,发现其实求$g[fa]$的时候非常的状态是重复的,能不能优化呢?

当然是可以的,画个美妙的图

那么,注意到以$fa$为根的子树包括$gf$的子树和$fa$除了$u$以外的子树

那么,只要能快速地调用除了$u$以外的所有子树转移值得乘积,就能解决左边的子树

同时,右边的子树可以调用$g[gf]$来快速转移

然后就是$O(n)$啦!

代码好像还加了点优化

年代久远了,忘了是什么优化了...

#include <cstdio>
#define dl double
#define sid 500050
#define ri register int
using namespace std; char RR[];
extern inline char gc() {
static char *S = RR + , *T = RR + ;
if(S == T) fread(RR, , , stdin), S = RR;
return *S ++;
}
inline int read() {
int p = , w = ; char c = gc();
while(c > '' || c < '') { if(c == '-') w = -; c = gc(); }
while(c >= '' && c <= '') { p = p * + c - ''; c = gc(); }
return p * w;
} int n, cnt;
dl a[sid], s[sid], f[sid], pi[sid * ];
int cap[sid], node[sid * ], nxt[sid * ]; void addedge(int u, int v, dl p) {
nxt[++ cnt] = cap[u]; cap[u] = cnt;
node[cnt] = v; pi[cnt] = 1.0 - p;
} void son_fa(int e, int fa) {
s[e] = - a[e];
for(int i = cap[e]; i; i = nxt[i]) {
int d = node[i];
if(fa == d) continue;
son_fa(d, e);
s[e] *= s[d] + ( - s[d]) * pi[i];
}
} void fa_son(int e, int fa) {
for(int i = cap[e]; i; i = nxt[i]) {
int d = node[i];
if(d == fa) continue;
dl P = f[e] / (s[d] + ( - s[d]) * pi[i]);
f[d] = (P + ( - P) * pi[i]) * s[d];
fa_son(d, e);
}
} int main() {
n = read();
for(ri i = ; i < n; i ++) {
int u = read(), v = read(), p = read();
addedge(u, v, p / 100.0); addedge(v, u, p / 100.0);
}
for(ri i = ; i <= n; i ++) {
int p = read();
a[i] = p / 100.0;
}
son_fa(, );
f[] = s[];
fa_son(, );
dl ans = ;
for(ri i = ; i <= n; i ++) ans += - f[i];
printf("%.6lf\n", ans);
return ;
}

luoguP4284 [SHOI2014]概率充电器 概率期望树形DP的更多相关文章

  1. [BZOJ3566][SHOI2014]概率充电器 换根树形DP

    链接 题意:n个充电元件形成一棵树,每个点和每条边都有各自的充电概率,元件可以自身充电或者通过其他点和边间接充电,求充电状态元件的期望个数 题解 设1为根节点 设 \(f[x]\) 表示 \(x\) ...

  2. 洛谷 P4284 [SHOI2014]概率充电器 概率与期望+换根DP

    洛谷 P4284 [SHOI2014]概率充电器 概率与期望+换根DP 题目描述 著名的电子产品品牌\(SHOI\) 刚刚发布了引领世界潮流的下一代电子产品-- 概率充电器: "采用全新纳米 ...

  3. 【BZOJ3566】[SHOI2014]概率充电器 期望+树形DP

    [BZOJ3566][SHOI2014]概率充电器 Description 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品——概率充电器:“采用全新纳米级加工技术,实现元件与导线 ...

  4. [BZOJ3566][SHOI2014]概率充电器(概率DP)

    题意:树上每个点有概率有电,每条边有概率导电,求每个点能被通到电的概率. 较为套路但不好想的概率DP. 树形DP肯定先只考虑子树,自然的想法是f[i]表示i在只考虑i子树时,能有电的概率,但发现无法转 ...

  5. 【NOIP2016提高A组集训第14场11.12】随机游走——期望+树形DP

    好久没有写过题解了--现在感觉以前的题解弱爆了,还有这么多访问量-- 没有考虑别人的感受,没有放描述.代码,题解也写得歪歪扭扭. 并且我要强烈谴责某些写题解的代码不打注释的人,像天书那样,不是写给普通 ...

  6. luogu P3412 仓鼠找sugar II 期望 树形dp

    LINK:仓鼠找sugar II 以前做过类似的期望题目 加上最后的树形dp不算太难 还是可以推出来的. 容易发现 当固定起点和终点的时候 可以先固定根 这样就不用分到底是正着走还是倒着走了. 1为根 ...

  7. bzoj 3566: [SHOI2014]概率充电器 数学期望+换根dp

    题意:给定一颗树,树上每个点通电概率为 $q[i]$%,每条边通电的概率为 $p[i]$%,求期望充入电的点的个数. 期望在任何时候都具有线性性,所以可以分别求每个点通电的概率(这种情况下期望=概率 ...

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

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

  9. [JZOJ 5911] [NOIP2018模拟10.18] Travel 解题报告 (期望+树形DP)

    题目链接: http://172.16.0.132/senior/#contest/show/2530/1 题目: EZ同学家里非常富有,但又极其的谦虚,说话又好听,是个不可多得的人才.        ...

随机推荐

  1. 阿里iconfont引入方法

    原文:iconfont的引入方法   第一步:使用font-face声明字体@font-face {font-family: 'iconfont';src: url('iconfont.eot'); ...

  2. 配置node,sass,淘宝镜像环境

    由于最近由于刚到手一台新的thinkpad(哈哈,宝宝是个小穷B,木有小苹果),所以工作开发中所用到的环境就需要重新安装一下啦,这里的话,我就把我目前所用到的进行总结一下,其余的会在以后的开发过程中, ...

  3. spring-boot-JdbcTemplate

    添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>sp ...

  4. java线上应用故障排查之二:高内存占用【转】

    前一篇介绍了线上应用故障排查之一:高CPU占用,这篇主要分析高内存占用故障的排查. 搞Java开发的,经常会碰到下面两种异常: 1.java.lang.OutOfMemoryError: PermGe ...

  5. Linux运维常用的几个命令介绍【转】

    Linux运维常用的几个命令介绍 1. 查看系统内核版本​ [root@funsion geekxa]# cat /etc/issue CentOS release 6.5 (Final) Kerne ...

  6. URAL题解一

    URAL题解一 URAL 1002 题目描述:一种记住手机号的方法就是将字母与数字对应,如图.这样就可以只记住一些单词,而不用记住数字.给出一个数字串和n个单词,用最少的单词数来代替数字串,输出对应的 ...

  7. BZOJ 2049: [Sdoi2008]Cave 洞穴勘测——LCT

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2049 省选之前来切一道数据结构模板题. 题意 这是一道模板题. N个点,M次操作,每次加边/ ...

  8. 设计模式之笔记--享元模式(Flyweight)

    享元模式(Flyweight) 定义 享元模式(Flyweight),运用共享技术有效地支持大量细粒度的对象. 类图 描述 Flyweight:抽象享元类,是所有的具体享元类的基类,为子类规定出需要实 ...

  9. 在Ubuntu上安装搜狗输入法

    1.进入搜狗输入法官网 2.下载Linux版本,选择64bit 下载 3.等待下载的同时,进行系统配置 进入系统设置->语言支持->进行更新(需要输入登录密码)->在键盘输入法系统选 ...

  10. python开发web服务器——搭建简易网站

    参看:https://blog.csdn.net/baidu_35085676/article/details/69807145