这道题。。。好像是第一道我自己切出来的黑题。。。
先说一句,牛顿二项式蒟蒻并不会,可以说是直接套结论。
求诸位老爷轻喷。
这道题用卡特兰数搞。
卡特兰数这玩意从普及组初赛一路考到省选,十分有用。
如果不清楚这个概念的话可以看一下这里。
卡特兰数是有两种计算方法:
1) 用递推算。
2) 用排列组合。
用它解题的流程一般是先说明所求的问题可以归到第一类中,然后再用第二类来计算具体的值。
像这道题就可以用卡特兰数水过。
我们假设(f_i)表示节点数为i的二叉树有多少种。
那么可以发现存在这样的关系:(f_i=sum_{k=1}^{i-1}f_{k}f_{i-k-1})。
这个东西满足卡特兰数的第一类表示方法。
所以运用第二类表示方法就可以得到(f_i=frac{1}{n+1}C^n_{2n})。
现在我们用(h_i)表示节点数为i的二叉树的叶子节点数量。
那根据(f_i)的值我们就可以得出递推式:(h_i=2sum_{k=0}^{i-1}h_kf_{i-k-1})
也就是(h_i=C^{i-1}_{2i-2})
那么最终的答案就是(frac{h_i}{f_i}=frac{C^{i-1}_{2i-2}}{frac{1}{n+1}C^n_{2n}}=frac{n(n+1)}{2(2n-1)})。
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#define qwq int
#define QAQ double
#define re register
using namespace std;
namespace Solve{
inline void read(qwq &x){
x=0;qwq f=1;char c=getchar();
for(;c<'0'||c>'9';c=getchar())if(c=='-')f=-1;
for(;c>='0'&&c<='9';c=getchar())x=x*10+c-'0';
x*=f;
}
qwq n;
QAQ ans;
inline void solve(){
read(n);
ans=(QAQ)n*(QAQ)(n+1)/(QAQ)(2*n-1)/2;
printf("%.9lf",ans);
}
}
using namespace Solve;
qwq main(){
solve();
}