您的位置:首页 > 其它

Codeforces 696B. Puzzles (概率DP求期望)

2016-07-16 17:16 267 查看
题目链接

简单题意

访问一颗树,在节点上记录访问时间,每次对儿子节点的访问是随机的,问每个节点被访问时间的期望

思路

很显然,如果先访问了兄弟节点,则会把兄弟节点的子树全部访问完成后再来下一次选择。所以要记录一下每个节点中子节点的个数,这个很简单,直接倒着扫一遍邻接表就累加行了。有了子节点的个数,我们还需要得到某一个节点先于其他节点被选择的概率,是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))))
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: