题意描述
为了提高智商,ZJY开始学习概率论.有一天,她想到了这样一个问题:对于一棵随机生成的\(n\)个结点的有根二叉树(所有互相不同构的形态等概率出现),它的叶子节点数的期望是多少呢?
判断两棵树是否同构的伪代码如下:
\(\text{CHECK}(T1,T2):\)
\(//\text{两棵树的节点}T1,T2\)
\(\mathbf{if}\ T1=\mathbf{NULL}\ \mathbf{or}\ T2=\mathbf{NULL}:\)
\(\quad \mathbf{return}\ T1=\mathbf{NULL}\ \mathbf{and}\ T2=\mathbf{NULL}\)
\(\mathbf{else}:\)
\(\mathbf{return}\ \text{CHECK}(T1.leftson,T2.leftson)\ \mathbf{and}\ \text{CHECK}(T1.rightson,T2.rightson)\)
分析
首先,我们令\(f_n\)表示\(n\)个点的二叉树个数;\(g_n\)表示\(n\)个点的所有\(f_n\)棵二叉树的叶节点总数.
找规律第一步当然是打表啦~写个爆搜或者手算都可以.
n | 1 | 2 | 3 | 4 | 5 | ... |
---|---|---|---|---|---|---|
\(f_n\) | 1 | 2 | 5 | 14 | 42 | ... |
\(g_n\) | 1 | 2 | 6 | 20 | 70 | ... |
我们发现一个规律:\(g_n\)=\(nf_{n-1}\).
证明这个规律其实超级简单:
- 对于每棵\(n\)个点的二叉树,如果里面有\(k\)个叶节点,那么我们分别把这\(k\)个叶子删去会得到\(k\)棵\(n-1\)个点的二叉树;
- 而每棵\(n-1\)个点的二叉树恰好有\(n\)个位置可以悬挂一个新的叶子,所以每棵\(n-1\)个点的二叉树被得到了\(n\)次;
- 综上,我们即可得出结论:所有\(n\)个点的二叉树的叶子个数和等于\(n-1\)个点的二叉树个数\(\times n\).
那么我们只需要求出\(f\)即可.而\(f\)的递推式可以通过枚举左子树结点个数得到:
\[
f_n=\sum_{i=1}^{n-1}f_if_{n-i-1}
\]
边界是\(f_1=1\).应该可以一眼看出来这是Catalan数列(其实一看那个\(1,2,5,14,421,2,5,14,42\)就应该知道)
于是答案即为
\[
\frac{g_n}{f_n}=\frac{nf_{n-1}}{f_n}
\]
代入卡特兰数的通项公式
\[
f_n=\frac{\binom{2n}{n}}{n+1}
\]
很容易就得到上式等于
\[
\frac{n(n+1)}{2(2n-1)}.
\]
Code
double n;
int main()
{
scanf("%lf",&n);
printf("%.12lf\n",n*(n+1)/(2*(2*n-1)));
}
原文地址:https://www.cnblogs.com/Anverking/p/solution-lgp3978.html