正题
题目大意
开始的时候一个点,然后等概率随机选一个叶子节点展开成两个,求nnn个叶子节点的树的叶子节点平均深度和最大深度期望。
解题思路
平均深度很好求,因为每展开一个,叶子节点总深度就加上个2。
所以gi=gi−1+2ig_{i}=g_{i-1}+\frac{2}{i}gi=gi−1+i2
然后考虑如何求最大深度。
设fi,jf_{i,j}fi,j为iii个节点深度≥j\geq j≥j,然后考虑一棵树,我们枚举一个子树的大小kkk,那么另一个就是i−ki-ki−k,然后展开一个的话fk,j−1f_{k,j-1}fk,j−1或fi−k,j−1f_{i-k,j-1}fi−k,j−1。但是因为都大于jjj的情况重复了,所以要加上一个fk,j−1∗fi−k,j−1f_{k,j-1}*f_{i-k,j-1}fk,j−1∗fi−k,j−1
fi,j=fk,j−1+fi−k,j−1−fk,j−1∗fi−k,j−1f_{i,j}=f_{k,j-1}+f_{i-k,j-1}-f_{k,j-1}*f_{i-k,j-1}fi,j=fk,j−1+fi−k,j−1−fk,j−1∗fi−k,j−1
之后答案就是∑i=1n−1fi\sum_{i=1}^{n-1}f_{i}i=1∑n−1fi
codecodecode
#include<cstdio>
using namespace std;
int q,n;
double g[110],f[110][110],ans;
int main()
{scanf("%d%d",&q,&n);if(q==1){g[1]=0;for(int i=2;i<=n;i++)g[i]=g[i-1]+(double)2/i;printf("%lf",g[n]);}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]/=(double)i-1;}for(int i=1;i<n;i++)ans+=f[n][i];printf("%lf",ans);}
}