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

题目描述

著名的电子产品品牌\(SHOI\) 刚刚发布了引领世界潮流的下一代电子产品—— 概率充电器:

“采用全新纳米级加工技术,实现元件与导线能否通电完全由真随机数决 定!\(SHOI\) 概率充电器,您生活不可或缺的必需品!能充上电吗?现在就试试看 吧!”

\(SHOI\) 概率充电器由\(n-1\) 条导线连通了\(n\) 个充电元件。进行充电时,每条导 线是否可以导电以概率决定,每一个充电元件自身是否直接进行充电也由概率 决定。随后电能可以从直接充电的元件经过通电的导线使得其他充电元件进行 间接充电。

作为\(SHOI\) 公司的忠实客户,你无法抑制自己购买\(SHOI\) 产品的冲动。在排 了一个星期的长队之后终于入手了最新型号的\(SHOI\) 概率充电器。你迫不及待 地将\(SHOI\) 概率充电器插入电源——这时你突然想知道,进入充电状态的元件 个数的期望是多少呢?

输入格式

第一行一个整数:\(n\)。概率充电器的充电元件个数。充电元件由\(1-n\) 编号。

之后的\(n-1\) 行每行三个整数\(a, b, p\),描述了一根导线连接了编号为\(a\) 和\(b\) 的 充电元件,通电概率为\(p\%\)。

第\(n+2\) 行\(n\) 个整数:\(q_i\)。表示\(i\) 号元件直接充电的概率为\(q_i\%\)。

输出格式

输出一行一个实数,为能进入充电状态的元件个数的期望,四舍五入到小 数点后\(6\) 位小数。

输入输出样例

输入 #1复制

3
1 2 50
1 3 50
50 0 0

输出 #1复制

1.000000

输入 #2复制

5
1 2 90
1 3 80
1 4 70
1 5 60
100 10 20 30 40

输出 #2复制

4.300000

说明/提示

对于\(30\%\)的数据,\(n≤5000\)。

对于\(100\%\)的数据,\(n≤500000,0≤p,q_i≤100\)。

分析

对于一个元件,它可以被与它相邻的多个元件所影响

如果我们想要一次求出所有的结果,\(DP\)的顺序是不好规定的

因此我们可以先随便选一个点作为根节点,求出每一个点自己点亮自己和被子树点亮的概率

这样选定的根节点求出的结果是正确的

我们就可以继续使用换根\(DP\)求出其他的值

如果求被点亮的概率转移比较麻烦,因此我们设\(f[i]\)为\(i\)不被点亮的概率

那么\(f[i]=(1.0-val[i,j]+val[i,j] \times f[j])\),\(j\)是\(i\)的儿子节点

如果\(i\)和\(j\)之间的边都没有通电,那么\(i\)被\(j\)点亮肯定是不可以的

即使边通了电,也要保证\(j\)通电才可以

换根的时候,我们定义\(g[i]\)为节点\(i\)通电的概率

对于之前的根节点,直接继承即可

对于其它任意一个节点\(i\),如果我们要更新儿子节点\(j\)的话

我们首先把\(j\)所在子树的价值从\(i\)中刨去

再用得到的值去更新\(g[j]\)即可

代码

#include<cstdio>
#include<cstring>
const int maxn=1e6+5;
int head[maxn],tot=1,n;
struct asd{
int to,next;
double val;
}b[maxn];
void ad(int aa,int bb,int cc){
b[tot].to=bb;
b[tot].next=head[aa];
b[tot].val=(double)cc*0.01;
head[aa]=tot++;
}
double f[maxn],p[maxn],g[maxn];
void dfs(int now,int fa){
f[now]=p[now];
for(int i=head[now];i!=-1;i=b[i].next){
int u=b[i].to;
if(u==fa) continue;
dfs(u,now);
f[now]*=(1.0-b[i].val+b[i].val*f[u]);
}
}
void dfs2(int now,int fa,double lat){
if(now==1){
g[now]=f[now];
} else {
double P=g[fa]/(1.0-lat+lat*f[now]);
g[now]=f[now]*(1.0-lat+lat*P);
}
for(int i=head[now];i!=-1;i=b[i].next){
int u=b[i].to;
if(u==fa) continue;
dfs2(u,now,b[i].val);
}
}
int main(){
memset(head,-1,sizeof(head));
scanf("%d",&n);
for(int i=1;i<n;i++){
int aa,bb,cc;
scanf("%d%d%d",&aa,&bb,&cc);
ad(aa,bb,cc);
ad(bb,aa,cc);
}
for(int i=1;i<=n;i++){
int aa;
scanf("%d",&aa);
p[i]=1.0-(double)aa*0.01;
}
dfs(1,0);
dfs2(1,0,0);
double ans=0;
for(int i=1;i<=n;i++){
ans+=(1.0-g[i]);
}
printf("%.6f\n",ans);
return 0;
}

洛谷 P4284 [SHOI2014]概率充电器 概率与期望+换根DP的更多相关文章

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

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

  2. 洛谷 P4284 [SHOI2014]概率充电器 解题报告

    P4284 [SHOI2014]概率充电器 题目描述 著名的电子产品品牌SHOI 刚刚发布了引领世界潮流的下一代电子产品-- 概率充电器: "采用全新纳米级加工技术,实现元件与导线能否通电完 ...

  3. Bzoj3566/洛谷P4284 [SHOI2014]概率充电器(概率dp)

    题面 Bzoj 洛谷 题解 首先考虑从儿子来的贡献: $$ f[u]=\prod_{v \in son[u]}f[v]+(1-f[v])\times(1-dis[i]) $$ 根据容斥原理,就是儿子直 ...

  4. 洛谷P3412 仓鼠找$Sugar\ II$题解(期望+统计论?)

    洛谷P3412 仓鼠找\(Sugar\ II\)题解(期望+统计论?) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1327573 原题链接:洛谷P3412 ...

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

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

  6. [SHOI2014]概率充电器(概率+换根dp)

    著名的电子产品品牌SHOI 刚刚发布了引领世界潮流的下一代电子产品—— 概率充电器: “采用全新纳米级加工技术,实现元件与导线能否通电完全由真随机数决 定!SHOI 概率充电器,您生活不可或缺的必需品 ...

  7. 洛谷P4332 [SHOI2014]三叉神经树(LCT,树剖,二分查找,拓扑排序)

    洛谷题目传送门 你谷无题解于是来补一发 随便百度题解,发现了不少诸如树剖\(log^3\)LCT\(log^2\)的可怕描述...... 于是来想想怎么利用题目的性质,把复杂度降下来. 首先,每个点的 ...

  8. 【洛谷3239_BZOJ4008】[HNOI2015] 亚瑟王(期望 DP)

    题目: 洛谷 3239 分析: 卡牌造成的伤害是互相独立的,所以 \(ans=\sum f_i\cdot d_i\) ,其中 \(f_i\) 表示第 \(i\) 张牌 在整局游戏中 发动技能的概率.那 ...

  9. 【洛谷1654/BZOJ4318】OSU!(期望DP)

    题目: 洛谷1654 分析: 本人数学菜得要命,这题看了一整天才看明白-- 先说说什么是"期望".不太严谨地说,若离散型随机变量(可以看作"事件")\(X\)取 ...

随机推荐

  1. Django学习路18_F对象和Q对象

    F 对象: 可以使用模型的 A 属性和 B 属性进行比较 写法: 需要的数据对象 = 数据表(类名).objects.filter(列名__条件=F('列名2')) 需求: 查看男生数量比女生少 的公 ...

  2. Python exec 内置语句

    描述 exec 执行储存在字符串或文件中的Python语句,相比于 eval,exec可以执行更复杂的 Python 代码.岭组词  https://www.cgewang.com/post/2205 ...

  3. PHP str_ireplace() 函数

    实例 把字符串 "Hello world!" 中的字符 "WORLD"(不区分大小写)替换成 "Peter": <?php高佣联盟 w ...

  4. CF EC 87 div2 1354 C2 Not So Simple Polygon Embedding 计算几何 结论

    LINK:Not So Simple Polygon Embedding 搞了好久终于搞会了. 错误原因 没找到合适算边长的方法 要么就是边长算的时候算错了. 几何学的太差了 最后虽然把十边形的和六边 ...

  5. log4j2 自动删除过期日志文件配置及实现原理解析

    日志文件自动删除功能必不可少,当然你可以让运维去做这事,只是这不地道.而日志组件是一个必备组件,让其多做一件删除的工作,无可厚非.本文就来探讨下 log4j 的日志文件自动删除实现吧. 0. 自动删除 ...

  6. 眼见为实 — CSS的overflow属性

    1. overflow属性 CSS的overflow属性指定当内容溢出一个元素的框,会发生什么.举个栗子: <!DOCTYPE html> <html> <head> ...

  7. JS 鼠标、键盘事件对象

    鼠标事件对象     mouseEvent鼠标事件对象     e.clientX 在可视区的x和y的坐标     e.pageX 在页面文档的X和Y的坐标 <script> docume ...

  8. Web 开发必须掌握的三个技术:Token、Cookie、Session

    在Web应用中,HTTP请求是无状态的.即:用户第一次发起请求,与服务器建立连接并登录成功后,为了避免每次打开一个页面都需要登录一下,就出现了cookie,Session. Cookie Cookie ...

  9. csapp第九章笔记-虚拟内存

    目录 物理与虚拟寻址 地址空间 虚拟内存作为缓存的工具 虚拟内存作为内存管理的工具 虚拟内存作为内存保护的工具 地址翻译 使用TLB(翻译后备缓冲器)加速地址翻译 多级页表 物理与虚拟寻址 计算机系统 ...

  10. C#LeetCode刷题之#628-三个数的最大乘积( Maximum Product of Three Numbers)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3726 访问. 给定一个整型数组,在数组中找出由三个数组成的最大乘 ...