题解 P3830 【[SHOI2012]随机树】
P3830 [SHOI2012]随机树解题报告:
更好的阅读体验
题意
- 最开始给定一个根结点,然后进行
n-1 次操作,每次随机选定一个叶子结点给它添加一对左右子结点,求: - 1.叶子结点平均深度的期望;
- 2.树深度的期望。
- 数据范围:
1\leqslant n\leqslant 100 。 - 注意:根结点深度为
0 。
分析
期望神仙题。
第一问
我们考虑一次对深度为
设
因为边界是
第二问
前置知识:正整数的期望公式,即对于正整数随机变量
x ,有E(x)=\sum_{i=1}^{\infty}P(x\geqslant i) 证明(须配合下方公式一同食用):
第一步很显然是期望的定义,第二步是一个差分(因为
x 是正整数),第三步就是拆了一下式子,可以发现因为i 趋近于无限,所以可以把求和挪过来一位,因此有了第四步(虽然没有可以挪到i=1 的式子,但因为i=1 时i-1=0 ,因此加上可以保持美观),最后相减就可以得到第五个式子了。E(x)=\sum_{i=1}^{\infty}P(x=i)\cdot i =\sum_{i=1}^{\infty}(P(x\geqslant i)-P(x\geqslant i+1))\cdot i =\sum_{i=1}^{\infty}P(x\geqslant i)\cdot i-\sum_{i=1}^{\infty}P(x\geqslant i+1)\cdot i =\sum_{i=1}^{\infty}P(x\geqslant i)\cdot i-\sum_{i=1}^{\infty}P(x\geqslant i)\cdot(i-1) =\sum_{i=1}^{\infty}P(x\geqslant i)
设
然后考虑如何求
解释:前面的
然后我们的问题到了怎么求
考虑如何证明,我们发现对左子树进行的操作是与右子树无关的,我们把所有操作分成扩展左子树和右子树,那么如果扩展了
通过组合数我们知道了选定哪些操作,而这些操作作用在不同的结点上又是不一样的方案,因此我们还需要计算作用在不同结点上一共有多少种方案。对于左子树,第一次可以作用的结点数为
将选定操作的方案数和作用在不同结点上的方案数相乘就是左子树
故转移方程为
代码
#include<stdio.h>
const int maxn=105;
int q,n;
double ans;
double f[maxn][maxn];
int main(){
scanf("%d%d",&q,&n);
if(q==1)
for(int i=2;i<=n;i++)
ans+=2.0/i;
if(q==2){
for(int i=1;i<=n;i++){
f[i][0]=1.0;
for(int j=1;j<i;j++)
for(int k=1;k<i;k++)
f[i][j]+=1.0/(i-1)*(f[k][j-1]+f[i-k][j-1]-f[k][j-1]*f[i-k][j-1]);
}
for(int i=1;i<n;i++)
ans+=f[n][i];
}
printf("%.6lf\n",ans);
return 0;
}