• [TJOI2015]概率论


    题目描述

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

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

    输入输出格式

    输入格式:

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

    输出格式:

    输出这棵树期望的叶子节点数,要求误差小于1e-9

    输入输出样例

    输入样例#1: 
    1
    输出样例#1: 
    1.000000000
    输入样例#2: 
    3
    输出样例#2: 
    1.200000000

    说明

    数据范围

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

    对于70%的数据,1 ≤ n ≤ 100

    对于100%的数据,1 ≤ n ≤ 10^9

         这可能是我见过思维含量和代码长度的比值最大的一道题了2333.

        首先有多项式恐惧症的人就不要往下看了2333,底下全是式子。

        首先设g[x] 为 节点数是 x 的二叉树有多少种,显然枚举根的左右子树可以得到: g[x] = Σ g[i] * g[x-i-1] 。特殊的,这里g[0]=1,表示空子树。

    可以发现这是一个卡特兰数的表示,所以直接得到通项: g[x] = (2x)!/(x!*x!*(x+1))。

        我们还可以设 多项式A = Σx^i * g[i] ,那么显然 A=x*A^2 + 1,我们解一下多项式之后发现它的闭形式为 (1-sqrt(1-4x))/2x。另一个根因为不收敛所以被舍去了。

        再设 f[i] 为i节点数为i的二叉树的叶子数的期望(显然 f[0]=0,f[1]=1),那么 f[x] =  Σ (f[i] + f[x-i-1]) * g[i] * g[x-i-1] /g[x] =     2*Σ f[i] * g[i] * g[x-i-1] /g[x] ,所以 g[x] * f[x] = 2*Σ f[i] * g[i] * g[x-i-1],我们就再设h[i] = f[i] * g[i] (显然h[0]=0,h[1]=1),设多项式B = Σx^i * h[i] 。那么可以得到: B=x*B*A + x,然后解一下多项式可以得到 B = x * (1-4x)^(-1/2)。

         其实我们可以先求 C = (1-4x)^(-1/2) ,然后把它右移一位就是B。

         也就是我们如果相求B中n次项前的系数的话,求一下C中的第n-1项就行了。

        解C的话,我们套用一下广义二项式定理(不会的请自觉百度),可以得到 C(n) = (-1/2)*(-1/2 - 1)*(-1/2 - 2)*....*(-1/2 - n+1)/ n! *(-4)^n 。强行化简一波发现上式 = (2n)!/(n!n!) ,所以 B(n) = (2n-2)!/((n-1)!(n-1)!)。

          也就是 h[i] = (2i-2)!/((i-1)!(i-1)!) ,所以 f[i] = h[i]/g[i] = i*(i+1)/(4*i-2)。

    然后就可以做到6行以内A一道较难省选题了2333

    #include<bits/stdc++.h>
    double a;
    int main(){
        scanf("%lf",&a);
        printf("%.11lf
    ",a*(a+1)/(2*(2*a-1)));
        return 0;
    }
    

      

  • 相关阅读:
    反编译工具
    3.25Java变量
    标识符
    OMS系统
    java打印方法区别
    注释
    写代码时候要注意的两个点
    python_pracyoce_day1
    SKU和SPU
    文档注释
  • 原文地址:https://www.cnblogs.com/JYYHH/p/8635246.html
Copyright © 2020-2023  润新知