zoukankan      html  css  js  c++  java
  • 洛谷P3978 [TJOI2015]概率论

    传送门

    rqy太强啦

    数学太差限制了我的想象力……我连卡特兰数是什么都不知道……姿势不够……

    令$f_i$表示有$i$个节点的二叉树的总个数,$g_i$表示$i$个节点的所有二叉树的叶子总数,那么答案就是$frac{g_n}{f_n}$

    不难发现$f_n$的递推式如下$$f_n=sum_{i=1}^{i-n-1}f_if_{n-i-1}$$

    就是枚举左子树里有几个点,那么右子树的点的个数就是总点数减去根减去左子树

    然后~~百度了一下~~发现这个东西就是卡特兰数,而卡特兰数的通项公式为$$f_n=C_{2n}^n$$

    于是就可以快速计算$f_n$了。现在考虑怎么计算$g_n$

    ~~看了rqy的表后~~不难发现$g_n=n imes f_{n-1}$。考虑如何证明

    设一棵树有$n$个节点,其中有$k$个叶节点,那么去掉每一个节点都能得到一棵$n-1$个节点的树,总共能得到$k$棵

    然后考虑对于每一个$n-1$个节点的树,有$n$个位置可以挂叶子(每个节点提供两个挂叶子的位置,有$n-2$地方已经被占了,剩下的就只有$n$个位置了)。于是每一棵$n-1$个节点的树会被得到$n$次。而每一种得到的方法都对应一个叶子。所以叶子结点总数为$f_{n-1}*n$

    那么答案就是$$ans=frac{g_n}{f_n}=frac{n*f_{n-1}}{f_n}$$

    把卡特兰数的通项公式带进去,化简之后得到$$ans=frac{n*(n+1)}{2*(2n-1)}$$

    不得不说这题真的太妙了

    1 //minamoto
    2 #include<cstdio>
    3 int main(){
    4     double n;scanf("%lf",&n);
    5     printf("%.12lf
    ",n*(n+1)/(2*(2*n-1)));
    6     return 0;
    7 }
  • 相关阅读:
    windbg学习.expr和masm表达式
    ThisCall调用分析
    windbg学习 gc j(Execute IfElse).if
    windbg学习¥{} Alias Interpreter 别名解释器
    windbg学习!vadump和.hh和!vprotc
    windbg学习 .lines
    windbg学习条件断点
    $<, $><, $$<, $$><, $$>a< (Run Script File)
    windbg学习?? 和 ?
    vimbook–OPL –official publications library
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9812239.html
Copyright © 2011-2022 走看看