题解 P3978 【[TJOI2015]概率论】

这道题。。。好像是第一道我自己切出来的黑题。。。

先说一句,牛顿二项式蒟蒻并不会,可以说是直接套结论。

求诸位老爷轻喷。


这道题用卡特兰数搞。

卡特兰数这玩意从普及组初赛一路考到省选,十分有用。

如果不清楚这个概念的话可以看一下这里

卡特兰数是有两种计算方法:

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=2\sum_{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();
}


posted @ 2018-10-25 16:18  Ilverene  阅读(174)  评论(0编辑  收藏  举报