CF696B Puzzles(期望dp)
Posted sdfzsyq
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF696B Puzzles(期望dp)相关的知识,希望对你有一定的参考价值。
解题思路
比较有意思的一道题。首先假如这个点(x)只有(1)个儿子(u),那么显然可得(dp[u]=dp[x]+1)。继续如果多加一个儿子(p),那么(p)在(u)前面的概率就是(1/2),也就是说(p)对于(u)的答案有(1/2)的可能产生贡献,而产生的贡献为(siz[p]),那么继续归纳下去,就可以得出转移方程。(dp[u]=dp[x]+1+(siz[x]-siz[u]-1)/2)。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int MAXN = 100005;
inline int rd(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)) {f=ch==‘-‘?0:1;ch=getchar();}
while(isdigit(ch)) {x=(x<<1)+(x<<3)+ch-‘0‘;ch=getchar();}
return f?x:-x;
}
int n,head[MAXN],cnt,to[MAXN],nxt[MAXN],siz[MAXN];
double ans[MAXN];
inline void add(int bg,int ed){
to[++cnt]=ed,nxt[cnt]=head[bg],head[bg]=cnt;
}
void dfs1(int x){
int u;siz[x]=1;
for(int i=head[x];i;i=nxt[i]){
u=to[i];dfs1(u);
siz[x]+=siz[u];
}
}
void dfs2(int x){
int u;
for(int i=head[x];i;i=nxt[i]){
u=to[i];ans[u]=ans[x]+1+(double)(siz[x]-siz[u]-1)/2;
dfs2(u);
}
}
int main(){
n=rd();int x;
for(int i=2;i<=n;i++)
x=rd(),add(x,i);
ans[1]=1.0;dfs1(1);dfs2(1);
for(int i=1;i<=n;i++) printf("%.8lf ",ans[i]);
return 0;
}
以上是关于CF696B Puzzles(期望dp)的主要内容,如果未能解决你的问题,请参考以下文章
CodeForces 696A(Lorenzo Von Matterhorn ) & CodeForces 696B(Puzzles )