正题
这题的题解都读了我半天呢///
首先我们来讨论第一问。。
我们设表示叶子结点为i时的叶节点平均深度。那么我们猜想一下,每次插入前的树的叶节点总深度平均为,因为每棵树上面每个节点的平均深度就是。另外我们讨论加点的平均深度。比如当前的树是左下角。
我们现在给它加上一个点,讨论其价值,平均每个点的深度是,我们就当作 这个点放在深度为的叶子节点上,那么原来的叶子节点会被覆盖,取而代之的是两个比它深度多1的节点。所以多出来的就是,然后我们再与前面的总深度 加起来,除以x, 就是当前叶子的平均深度。
后面求树深度的期望。
用表示有i个叶子节点,深度>=j的概率。
那么很明显预处理都为1,因为深度不可能小于0;
继续往下推
我们不断地枚举左边子树的大小,然后令左右子树有一个深度>=j-1,都大于等于也行,但是会重复算,所以要减去两个相乘。
最后的答案就是
因为第k个会被前面算k遍,就相当于给深度为k的概率乘上一个k。
代码简单看看就行,关键还是理解。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;
int n,q;
double f[110][110];
int main(){
scanf("%d %d",&q,&n);
if(q==1){
double ans=0;
for(double i=2;i<=n;i++) ans+=2/i;
printf("%lf",ans);
return 0;
}
else{
for(int i=1;i<=n;i++) f[i][0]=1;
for(int i=2;i<=n;i++)
for(int j=1;j<i;j++){
for(int k=1;k<i;k++)
f[i][j]+=f[k][j-1]+f[i-k][j-1]-f[k][j-1]*f[i-k][j-1];
f[i][j]/=(i-1);
}
double ans=0;
for(int i=1;i<n;i++) ans+=f[n][i];
printf("%lf",ans);
}
}
其实你再给我一道这样的题,我还是不会的。要多积累啊!!