http://www.elijahqi.win/archives/1775
Description
Input
输入一个正整数N,代表有根树的结点数
Output
输出这棵树期望的叶子节点数。要求误差小于1e-9
Sample Input
1
Sample Output
1.000000000
HINT
1<=N<=10^9
公式推导题:
首先需要知道卡特兰数的组合公式
这题主要根据生成函数推导得到
我们知道卡特兰数的递推式是类似卷积f[n]=sigma(i=1~n-1)h[i]*h[n-i](可能描述有问题我很渣渣的
我们把卡特兰数作为生成函数的系数
f(x)=1+x+2*x^2+5x^3+14x^4+…
那么把这个函数平方我们可以发现和原函数的一下关系
f(x)=x*f(x)^2+1 我们可以知道我枚举子树的形态的时候恰好就是卡特兰数种个数
那么期望我就用总的叶子节点的数/子树形态的个数即可
那么算叶子节点的个数也可以使用这种方法
那么我可以枚举左边分配几个节点 他的叶子节点是多少 那么我右边的形态是不固定的我可以用卡特兰数算出
这里贴了一个其他blog的一部分 这样应该比较简单易懂
那么我们该怎么求叶子节点的个数 当然还是使用生成函数 我把H(x)的通项公式带入 即可求出F(x)的通项公式
这个F(x)底下的式子可以使用牛顿二项式进行展开
然后就可以求得通项公式
这个是官方题解截出来的这里的C这个生成函数就是我的那个F函数
关于牛顿二项式定理的使用主要有一个C(-1/2,i)这个不好办
我们可以考虑我们一半的组合数是如何计算的是不是比如C(n,2)就是n*(n-1)/2*1
同理牛顿二项式我们可以变成-1/2*((-1/2)-1)*..这样乘i项
然后底下是i! i的阶乘即可开始计算了
关于推导卡特兰数通项公式的一些心得:
由于上面的生成函数可以知道是H(x)的那个形式 接下来继续使用牛顿二项式定理进行展开 展开到最后我们可以把sigma中i=0的一项和前面的1消去
然后剩下的东西我们考虑在我分式上下同乘i!
那么我就可以把上面变成一个2(n-1)!
下面变成i!*(i-1)!然后就可以继续化简变成o(1)的卡特兰数公式了
最后附上我参考的blog的地址http://blog.miskcoo.com/2015/04/bzoj-4001
#include<cstdio>
double n;
int main(){
scanf("%lf",&n);printf("%.9f",n*(n+1)/(2*(2*n-1)));
return 0;
}