【BZOJ4001】概率论(TJOI2015)-生成函数+卡特兰数+微积分
测试地址:概率论
做法:本题需要用到生成函数+卡特兰数+微积分。
令为个节点的不同构的二叉树数目,我们知道这就是卡特兰数。再令为个节点的所有不同构的二叉树的叶子节点数总和。答案显然就是。
首先很快得出的递推式:
令分别为的生成函数,根据的递推式:
发现很是一个卷积的形式,但是右边算的卷积会被放在的位置上,要使它放在的位置上需要往右移一位,在生成函数上的体现就是乘个。别忘了补一个来表示。于是有:
解一元二次方程得:(分子那个为什么不能取尚不了解,但往下算到某一步能看出不行)。
我们用相似的方式分析的递推式,有:
将前面求出的代入计算,得到:
有了的表达式,但是怎么把它写成级数展开的形式呢?直接泰勒展开?太麻烦了。我们注意到:
的导数是(用链式法则计算)。
也就是说:
(当时)
于是我们有:
(表示的导函数)
这就变成了对生成函数乘和求导的问题。乘就相当于数列向后移位,那么求导是什么呢?因为生成函数是一个多项式,因此可以每一项分开求导。因此我们有:
因此,所以。
有因为我们知道是卡特兰数,所以,那么把组合数拆开化简得:
于是寥寥几行代码就解决了这个问题(这真的不是在考数学么……)。
(当然你要是打表找规律或者硬是通过组合意义得出这个式子我也没有意见……)
以下是本人代码:
#include <bits/stdc++.h>
using namespace std;
double n;
int main()
{
scanf("%lf",&n);
printf("%.9lf",n*(n+1.0)/(2.0*(2.0*n-1.0)));
return 0;
}