P4284 [SHOI2014]概率充电器


今天上课讲到的题orz,第一次做这种上下搞两次dp的题。

g[i]表示i的子树(包括i)给i充电的概率。

f[i]表示i的父亲给i充电的概率。

g[]可以快速求出来。h[i]表示i对i父亲的贡献,则

\(h_i=g_i+(1-g_i)(1-w(i,fa_i))\)

\(g_i=(1-q_i)\Pi_{j=son}h_j\)

\(w(i,fa_i)\)即\(i\)与\(fa_i\)之间路径的长度。

但是f[]就不好求了= =

上面已经求出了f[y],要求f[x]。f[x]需要计算除了x的子树之外的所有点。

可以把这些点分成两部分:绿色和紫色部分

紫色部分就是f[y],但绿色呢?

回去看一眼:\(g_y=(1-q_y)\Pi_{j=son}h_j\)

所以只需要除掉\(h_x\)就星了。

\(t=\frac{g_yf_y}{h_x}\)

\(f_x=t+(1-t)(1-w(x,y))\)

注意t不是\(f_x\),t是去掉x子树后y通电的概率,可参照h的求法


上述方法可获得95分的好成绩。

因为\(t=\frac{g_yf_y}{h_x}\),如果遇到0就GG了。。。

观察一下,\(h_x=0\)的话,t实际是0(因为上面一定会通电下来??

然后写完了= =

  1. #include<cstdio>
  2. #include<cstdlib>
  3. #include<algorithm>
  4. #include<cctype>
  5. using namespace std;
  6. typedef int mmp;
  7. #define vd void
  8. #define rg register
  9. #define il inline
  10. #define sta static
  11. il int gi(){
  12. int x=0,f=1;char ch=getchar();
  13. while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
  14. while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
  15. return x*f;
  16. }
  17. const int maxn=500001;
  18. int id,fir[maxn],nxt[maxn<<1],dis[maxn<<1],w[maxn<<1];
  19. int p[maxn];
  20. il vd link(int x,int y,int z){nxt[++id]=fir[x],fir[x]=id,dis[id]=y,w[id]=z;}
  21. double f[maxn],g[maxn],h[maxn];
  22. il vd dp(int x,int fa=-1){
  23. g[x]=1-p[x]*.01;
  24. for(rg int i=fir[x];i;i=nxt[i]){
  25. if(fa==dis[i])continue;
  26. dp(dis[i],x);
  27. h[dis[i]]=g[dis[i]]+(1-g[dis[i]])*(1-w[i]*.01);
  28. g[x]*=h[dis[i]];
  29. }
  30. }
  31. il vd dp2(int x,int fa=-1){
  32. for(rg int i=fir[x];i;i=nxt[i]){
  33. if(fa==dis[i])continue;
  34. double t=(h[dis[i]]<1e-6)?0:g[x]*f[x]/h[dis[i]];
  35. f[dis[i]]=t+(1-t)*(1-w[i]*.01);
  36. dp2(dis[i],x);
  37. }
  38. }
  39. mmp main(){
  40. // freopen("4284.in","r",stdin);
  41. // freopen("4284.out","w",stdout);
  42. int n=gi();
  43. for(rg int i=1;i<n;++i){
  44. sta int a,b,p;
  45. a=gi(),b=gi(),p=gi();
  46. link(a,b,p),link(b,a,p);
  47. }
  48. for(rg int i=1;i<=n;++i)p[i]=gi();
  49. dp(1);f[1]=1;dp2(1);
  50. double ans=0;
  51. for(rg int i=1;i<=n;++i)ans+=1-f[i]*g[i];
  52. printf("%.6lf\n",ans);
  53. // for(rg int i=1;i<=n;++i)printf("%.6lf ",f[i]);puts("");
  54. // for(rg int i=1;i<=n;++i)printf("%.6lf ",g[i]);puts("");
  55. // for(rg int i=1;i<=n;++i)printf("%.6lf ",h[i]);puts("");
  56. return 0;
  57. }

P4284 [SHOI2014]概率充电器的更多相关文章

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

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

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

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

  3. P4284 [SHOI2014]概率充电器 dp

    这个题题干说的不清楚,一开始我以为只能是旁边紧挨着的传火,导致我一开始根本不知道哪错了.后来,我想到树形dp,但是需要正反考虑,()既要考虑父亲,又要考虑儿子),互相都有影响,所以没太想出来.后来知道 ...

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

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

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

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

  6. 【题解】Luogu P4284 [SHOI2014]概率充电器

    原题传送门 我们知道,每个电器充电对充电电器数的贡献都是相等的1,所以若第\(i\)个电器有\(p_i\)的概率充电时 \[E=\sum_{i=1}^np_i\] 我们考虑如何求\(p_i\),根据树 ...

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

    通过一次dfs求出dp(x)表示节点x考虑了x和x的子树都没成功充电的概率, dp(x) = (1-p[x])π(1 - (1-dp[son])*P(edge(x, son)).然后再dfs一次考虑节 ...

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

    3566: [SHOI2014]概率充电器 题意:一棵树,每个点\(q[i]\)的概率直接充电,每条边\(p[i]\)的概率导电,电可以沿边传递使其他点间接充电.求进入充电状态的点期望个数 糖教题解传 ...

  9. BZOJ3566: [SHOI2014]概率充电器 树形+概率dp

    3566: [SHOI2014]概率充电器 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1888  Solved: 857[Submit][Stat ...

随机推荐

  1. 固定UIScrollView滑动的方向

    固定UIScrollView滑动的方向 一般而言,我们通过这两个参数CGRectMake以及contentSize就可以自动的让UIScrollView只往一个方向滚动.但我遇到过非常奇葩的情况,那就 ...

  2. git五分钟教程

    使用Git前,需要先建立一个仓库(repository).您可以使用一个已经存在的目录作为Git仓库或创建一个空目录. 使用您当前目录作为Git仓库,我们只需使它初始化. git init 使用我们指 ...

  3. 【1】python-正则表达式语法规范与案例

    正则表达式的用法与案例分析 2018-08-24 21:26:14 [说明]:该文主要为了随后复习和使用备查,由于做了word文档笔记,所以此处博文没有怎么排版,没放代码,以插入图片为主, 一.正则表 ...

  4. 我的Java之旅——第一个Java程序

    在简单的看了一点Java的基本内容后,我开始尝试写自己的第一个Java程序.由于某些原因,学校官方的教务APP看不了自己这学期的平均绩点,就想着自己动手,写一小段代码,算一下自己的平均绩点.程序的功能 ...

  5. JavaScript基础之数据类型部分总结

    JavaScript 是世界上最流行的脚本语言,被设计为向 HTML 页面增加交互性. 我把它的基础语法分为了三个部分:数据类型,运算符,流程控制语句.入门还是比较容易的. 基本概念: 标识符:指变量 ...

  6. UE4的csv文件导入、URL地址的读取及动态材质的设置

    1.csv文件的导入 UE4是可以直接导入csv文件的,其过程和其他文件资源(图片Texture,静态网格物体StaticMesh等)相似,但在导入过程中有一些需要注意的点. 如下图所示 这是一份编辑 ...

  7. 通过golang 查询impala

    cloudera官方没有提供impala基于golang的驱动,github有github.com/bippio/go-impala package main import ( "conte ...

  8. sql按月模糊查询

    select * from tb where convert(varchar(7),date,120) = '2011-05'

  9. 20155314 2016-2017-2 《Java程序设计》第1周学习总结

    20155314 2016-2017-2 <Java程序设计>第1周学习总结 学习目标 了解Java基础知识(已完成) 了解JVM.JRE与JDK,并下载.安装.测试JDK(已完成) 了解 ...

  10. mysql 二进制日志binary log操作简单命令

    show master status \G; #查看当前正在记录的二进制日志 show binary logs; #查看binary log 所有文件列表 show binlog events; #查 ...