洛谷 P3978 [TJOI2015] 概率论 省选/NOI

题目描述

为了提高智商,ZJY 开始学习概率论。有一天,她想到了这样一个问题:对于一棵随机生成的 �n 个结点的有根二叉树(所有互相不同构的形态等概率出现),它的叶子节点数的期望是多少呢?

判断两棵树是否同构的伪代码如下:

算法 1Check(�1,�2)1Require:  两棵树的节点�1,�22if  �1=null or �2=null then 3return  �1=null and �2=null4else5return Check(�1→�������,�2→�������) and Check(�1→���ℎ����,�2→���ℎ����)6endif算法 1123456​Check(T1,T2)Require:  两棵树的节点T1,T2if  T1=null or T2=null then return  T1=null and T2=nullelsereturn Check(T1→leftson,T2→leftson) and Check(T1→rightson,T2→rightson)endif​​

输入格式

输入一个正整数 �n,表示有根树的结点数。

输出格式

输出这棵树期望的叶子节点数,要求误差小于 10−910−9。

输入输出样例

输入 #1

1

输出 #1

1.000000000

输入 #2

3

输出 #2

1.200000000

说明/提示

数据范围

对于 30% 的数据,1≤n≤10。

对于 70% 的数据,1≤n≤1001。

对于 100的数据,1≤n≤109。

解题思路:

首先,我们令��fn​表示�n个点的二叉树个数;��gn​表示�n个点的所有��fn​棵二叉树的叶节点总数。

找规律第一步当然是打表啦~写个爆搜或者手算都可以。

n12345...
��fn​1251442...
��gn​1262070...

我们发现一个规律:��=���−1gn​=nfn−1​。

证明这个规律其实超级简单:

  • 对于每棵�n个点的二叉树,如果里面有�k个叶节点,那么我们分别把这�k个叶子删去会得到�k棵�−1n−1个点的二叉树;
  • 而每棵�−1n−1个点的二叉树恰好有�n个位置可以悬挂一个新的叶子,所以每棵�−1n−1个点的二叉树被得到了�n次;
  • 综上,我们即可得出结论:所有�n个点的二叉树的叶子个数和等于�−1n−1个点的二叉树个数×�×n。

那么我们只需要求出�f即可。而�f的递推式可以通过枚举左子树结点个数得到:

��=∑�=1�−1����−�−1fn​=i=1∑n−1​fi​fn−i−1​

边界是�1=1f1​=1。应该可以一眼看出来这是Catalan数列(其实一看那个1,2,5,14,421,2,5,14,42就应该知道,滑稽)

于是答案即为

����=���−1��fn​gn​​=fn​nfn−1​​

代入卡特兰数的通项公式��=(2��)�+1fn​=n+1(n2n​)​很容易就得到上式等于�(�+1)2(2�−1)2(2n−1)n(n+1)​。

代码如下:

#include<bits/stdc++.h>
using namespace std;
int main(){
    double n;
    scanf("%lf",&n);
    printf("%.9f",n*(n+1)/(2*(2*n-1)));
    return 0;
}

拜拜! 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值