概率论

首先考虑当节点数为n时,有多少个二叉树

f[i]表示节点为i时二叉树的个数,有

f[n]=i=1n1f[i]f[n1i]

注意这种递推式子也是卡特兰数的一种形式,所以为卡特兰数

其实想到这个式子的话,我们可以借鉴随机树一题,从序列生成的角度去思考,于是我们就可以往确定左子树和右子树的序列去想,然后就可以想到这个递推公式了

注意无论从这个递推公式还是题面给的伪代码来看,以下两个树是不一样的

其实手写出前四项为1,2,5,14我们就要有足够的敏感度知道这是卡特兰数(找不出规律来的时候一定要学会打表啊)

然后考虑叶子个数,从类似刷表法的思想去考虑每个旧图产生的新图的贡献

我们假设我们已经画出了n个节点时所有的二叉树,那么不难发现,每一个二叉树可以再生成(n+1)张图

对于一个n个节点的二叉树,我们设a,b,c分别为叶子,度数为1,度数为2的节点的数量,一个方程就是a+b+c=n,这是通过点来列的方程;另一个方程就是b+2c=n1,这是通过边来列的方程(想下为什么对);于是通过两个方程可算出2a+b=n+1,也就是能产生的新图的数量

然后我们让所有的二叉树都生成(n+1)张图,我们只要把这些图中重复的去掉就好了

假设生成的一张图的叶子有d个,那么这张图肯定被重复生成了d次(每次都是在n个节点的所有二叉树的某一颗上添加一个叶子形成的),那么这张图的总贡献为d2,但他本来应该只贡献d,所以我们要去重

我们只要让每一张生成的图的原始贡献从d变为1即可,这样直接累加就是d个1相加而不是d个d相加了,刚好与他应该的贡献相同

所以(n+1)个节点的叶子数之和就是(n+1)*catn,其中catn为卡特兰数,代表n个节点的二叉树数目,n+1就是这些二叉树中的每一所能生成的图的数量(每个图的贡献都为1了)

update 2024.3.14

我觉得上述做法应该是有问题的(除了证明为什么可以插n个节点的那个位置),这道题目生成树的方式是直接生成的n个点的树,而不是一步一步生成的,所以我们最好不要按上面的过程思考(其实本质也没错,上述过程其实就是在找n个节点的树的叶子节点数量的总和,更详细的过程还是见下文吧)。我们可以参考题解一题解二。第一篇题解的思路是基于,每一张图的概率都是一样的,所以我们不用过多纠结于单个树的叶子节点是多少,而是直接求总的叶子节点数,以后在概率相同的时候可以往这方面思考。第二篇题解是对第一篇题解的解释,我来再说明一下。相当于,我们对任意一颗n个节点的树,假设有k个叶子节点,那么他删除掉任何一个叶子节点后,都会对应某一颗n1个节点的树,然后我们在这两幅图之间连边,那么对于这幅n个节点的树,显然会连k条边出去。对涉及的这kn1个节点的树,如果我们对每一颗树的某一个位置添加一个节点,就会变成这幅n个节点的树,我们显然总共会选择出k个节点,而且涉及的每一颗n1个节点的树刚好会被选出一个位置。我们对所有的n个节点的树都执行这个操作,执行完之后,我们再来观察n1个节点的树,不难发现,每棵树都刚好有n条边(因为能生成n颗树),而且对每棵树的n个位置(这n个位置生成了n条边),我们任选一个点生成一颗n个节点的树,就会有一条边被删除,而且每个位置对应删除的边是不同的(不然n个节点的树就同构了),根据对应关系,我们如果把所有边都删除完了也就获得了所有n个节点的树的叶子节点个数和。而我们总共需要删除nfn1条边,所以有结论。也就是说题解通过期望的定义去解决这道问题。由于每棵树的概率都一样,所以我们统计叶子节点总数,而统计叶子节点总数就在nn1之间建立联系即可

update 2024.8.11

注意找b,c的关系的时候不要用握手定理,因为根节点没有连向父亲的边,用了握手定理得出来的b不是我们要的那个b

posted @   最爱丁珰  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示