Codeforces 696B. Puzzles (概率DP求期望)
2016-07-16 17:16
267 查看
题目链接
简单说明一下,例如某个节点有a,b,c,d四个子节点,则可能产生24种排列,在所有的排列中,任意一点先于另外一点的概率是0.5,所以对于任意一个点,他先于另外某一个点被访问的概率是0.5。
没有被选中额外花费的时间为父亲的所有子节点数,减去当前节点及其子节点数。
所以得到转移方程为(i是父亲节点,to是儿子结点)
ans[to] = ans[i] + 1 + (sz[i]-1-sz[to]) * 0.5
简单题意
访问一颗树,在节点上记录访问时间,每次对儿子节点的访问是随机的,问每个节点被访问时间的期望思路
很显然,如果先访问了兄弟节点,则会把兄弟节点的子树全部访问完成后再来下一次选择。所以要记录一下每个节点中子节点的个数,这个很简单,直接倒着扫一遍邻接表就累加行了。有了子节点的个数,我们还需要得到某一个节点先于其他节点被选择的概率,是0.5简单说明一下,例如某个节点有a,b,c,d四个子节点,则可能产生24种排列,在所有的排列中,任意一点先于另外一点的概率是0.5,所以对于任意一个点,他先于另外某一个点被访问的概率是0.5。
没有被选中额外花费的时间为父亲的所有子节点数,减去当前节点及其子节点数。
所以得到转移方程为(i是父亲节点,to是儿子结点)
ans[to] = ans[i] + 1 + (sz[i]-1-sz[to]) * 0.5
代码
n = int(input()) pos,tree,ans,sz = list(map(int,input().split())) if n > 1 else [],[],[],[] for i in range(n): tree.append([]) ans.append(0.0) sz.append(0) for i in range(n-1): tree[pos[i]-1].append(i+1) for i in range(n)[::-1]: sz[i] = 1 for to in tree[i]: sz[i] += sz[to] for i in range(n): for to in tree[i]: ans[to] = ans[i] + 1 + (sz[i]-1-sz[to]) * 0.5 st = lambda i: str(i+1) print(' '.join(list(map(st,ans))))
相关文章推荐
- Java集合类库 LinkedList 源码解析
- 使用Maven 整合Spring和hibernate 适合初级接触的学者
- Ubuntu的网络配置
- CF 501D,树状数组+数学分析
- 分布式技术一周技术动态图2016-07-16
- Linux下查看磁盘分区命令详解
- 剑指offer----最小的k个数----java实现
- c++内存
- 变形的杨辉三角形--华为
- frist Django app — 五、Test
- Android 代码中setTextColor
- Android对话框 Dialog
- S5PV210 FIMC驱动和v4l2驱动框架学习
- C语言冒泡排序算实现代码
- 一个android群组通知APP的数据框架
- Android 开发你需要了解的 Gradle 配置
- ARM交叉编译工具链的制作
- 用Dialog实现确认对话框
- 函数式编程相关概念 - 笔记1
- [暑假集训] jzoj 2016.7.16 noip模拟赛B 总结