zoukankan      html  css  js  c++  java
  • 09 卡特兰数 伯努利数 贝尔数 (斯特林数 生成函数)待补

    卡特兰数

    定义

      卡特兰数(Catalan number)来自如下这样一个问题:

       

      从$(0,0)$出发,最终到达$(n,n)$。按照如下要求移动:

    ·每次移动只能向上或者向右移动;

    ·不越界,任意时刻的位置均在区域内;

    ·不过线,任意时刻的位置都在红线上或者红线下方。

    共有多少种移动方案?满足上述条件的数就是卡特兰数

    计算

      正面直接推算较为困难,考虑卡特兰数$=$总方案数$-$不合法方案数。可以得到总方案数为

    $$total=left( egin{array}{c}
    2n\
    n\
    end{array} ight) $$

     

    对于任意一个超过红线的位置,

    绿线为过该点且斜率为$1$的直线,将后续路线延绿线翻折。

    发现所有的终点均为$(n-1,n+1)$,故有:

    $ ext{illegal}=left( egin{array}{c}
    2n\
    n-1\
    end{array} ight) $

     

     

      最后就可以得到卡特兰数的通项公式:

    $$C_n=left( egin{array}{c}
    2n\
    n\
    end{array} ight) -left( egin{array}{c}
    2n\
    n-1\
    end{array} ight) $$

      对于递推公式,考虑过程中经过了某一点$(i,i)$,那么此时的方案数为$C_{i-1} C_{n-i}$,可以得到递推公式:

    $$
    C_n=left{ egin{array}{c}
    1,n=0\
    sum_{i=1}^n{C_{i-1}C_{n-i}}\,\,,n e 0\
    end{array} ight.
    $$

    思考题

     1.现有一个包含$n$个元素的栈,则总共有多少种出栈顺序?

      首先想一下,将情况进行分类,假设最后一个出栈的元素是$i$,那么在$i$入栈之前$1 sim i-1$都已出栈,在$i$出栈之前$i+1 sim n$都已出栈,计$i$个元素的出栈方式的方案数为$N_i$,则有递推式:

    $$
    N_n=left{ egin{array}{c}
    1,n=0\
    sum_{i=1}^n{N_{i-1}N_{n-i}}\,\,,n e 0\
    end{array} ight.
    $$

      即为卡特兰数。

      或者这样考虑,出栈的次数必定小于等于入站的次数,共出栈入栈$n$个元素,所以方案数直接就是卡特兰数。

     2.规律总结

     一般分析的角度有两种:

      第一种就是有两种操作或者属性$A$和$B$,满足$A ge B$,且$A$和$B$都需要进行$n$次,那么这就是一个卡特兰数;

      第二种就是找到上述形式的递归公式,一般都是采取一个中间过程的情况然后前后的情况数各是一个子问题。由于俩者相互独立,所以乘积就是该情况下的方案数。

     伯努利数

    定义

      伯努利数(Bernoulli number)源自于这样一个问题,对于如下多项式$P_k(n)$,求出其表达式:

    $$
    P_kleft( n ight) =1^k+2^k+3^k+...+n^k
    $$

      以上这个问题也称为等幂求和问题,当$k=1,2,3$是就是我们熟知的求和公式。整个的证明过程较为繁琐,这里给出一个链接,讲解的非常的详细,基本看了就可以听懂。我在这里给出每一个阶段的结果。

    1.帕斯卡初步给出的递推公式

    $$
    P_kleft( n ight) =frac{left( n+1 ight) ^{k+1}-1}{k+1}-frac{1}{k+1}sum_{i=0}^{k-1}{C^i_{k+1}P_ileft( n ight)}
    $$

      这是最早的一个递推公式,看似好像解决了问题其实不然。仔细观察会发现右侧求和部分中的$P_i(n)$其实是相当繁琐的,每要求出下一个就需要将前$n-1$个全部求出并每次乘上一个不同的数。这对于当代由计算机的帮助可能没什么,但是在当时看来是相当繁琐的。所以人们有致力于研究一个不那么依靠前项递推式以求简化计算。

    2.伯努利给出的递推式

    $$
    P_kleft( n ight) =sum_{i=0}^k{C_{k}^{i}P_i'left( 0 ight) frac{n^{k+1-i}}{k+1-i}}
    $$

      可以看到,现在左侧的计算式与$P_k(n)$本身已经无关了,甚至与$n$也无关了,只要给出这个常数列就可以更加高效的计算等幂求和的结果。而$P_i'left( 0 ight)$正是伯努利数$B_i$。再对上式中的$n$取特殊值并变形,得到了伯努利数的递推公式:

    $$
    B_k=left{ egin{array}{c}
    1,k=0\
    1-frac{1}{k+1}sum_{i=0}^{k-1}{C_{k+1}^{i}B_i},kge 1\
    end{array} ight.
    $$

      以上就是最终给出的伯努利数的递推定义,此外还有生成函数定义(太高级了我不会)有兴趣可以去问问度娘。

      再将其带入到原本的等幂求和问题中,有:

    $$
    P_kleft( n ight) =frac{1}{k+1}sum_{i=0}^k{left( -1 ight) ^iC_{k+1}^{i}B_in^{k+1-i}}
    $$

      可以看出最终的答案预处理的复杂度只和$k$相关,为$O(k^2)$的,与处理过后对于某一确定的$k$值,计算其结果的复杂度为$O(k)$。而伯努利数的预处理时间也与$k$有关,为$O(k^3)$。所以整体的复杂度为预处理$O(k^3)$,计算答案为$O(k)$。

      对于原本的直接求法,利用快速幂可知其复杂度为$O(nlogk)$。所以当$n$较小时,可以直接用朴素算法且该算法对$k$的限制很小,经测试当$n=1e5,k=1e18$时,只需$55 ms$就可以算出答案;当$n$很大但是$k$却较小时,可以利用伯努利数生成系数,然后再进行求解。

    一些性质

    由递推关系式可以简单推出:

      1.当$n ge 1$时,有$B_{2n+1}=0$

      2.当$n ge 2$时,有

    $$sum_{i=0}^n{C_{n+1}^{i}B_i}=0$$

    贝尔数

    定义

    贝尔数(Bell number)(标准开头)源自于集合划分问题:给出一个含有$n$个元素的集合,将其划分为互不相交的任意非零集合的个数是多少?

    这个其实很简单,考虑某一个元素,为了方便考虑设其为$a_{n}$。

    若将$a_n$单独分为一个子集,那么该情况的个数为$C_{n-1}^{0} B_{n-1}$;

    若将$a_n$和另一个元素分为一个子集,那么该情况的个数为$C_{n-1}^{1} B_{n-2}$;

    若将$a_n$和另外$i-1$个元素分为一个集合,那么该情况的个数为$C_{n-1}^{2}B_{n-i}$;

    由此得到贝尔数的递推关系式:

    $$
    B_{n+1}=sum_{i=0}^n{C_{n}^{i}B_i}
    $$

    特殊的$B_0=1,B_1=1$。

    性质

    1.满足Touchard同余(又出现了不知道的东西,无底洞)

    如果$p$为质数,则有:

    $$
    B_{p+n}=B_n+B_{n+1}\,\,mod\,\,p
    \
    B_{p^m+n}=mB_n+B_{n+1}\,\,mod\,\,p
    $$

      由于上述性质,可以看出其实贝尔数是周期模$p$的。当式中的$m$增长为$p$时就开始了新的周期,所以其周期为$N_p=cfrac{p^p-1}{p-1}$。上面这两个是我搜到的考得最多的,基本都是这两了。

     2.贝尔三角形

      通常的计算方法都是生成贝尔三角形其空间时间复杂度均为$O(n^2)$: 

    $$
    egin{matrix}
    1& & & & & & \
    1& 2& & & & & \
    2& 3& 5& & & & \
    5& 7& 10& 15& & & \
    15& 20& 27& 37& 52& & \
    52& 67& 87& 114& 151& 203& \
    ...& ...& ...& ...& ...& ...& ...\
    end{matrix}
    $$

    其满足如下规律:

      ·任意一个数等于其左侧和左上数的和;

      ·对于每一行的第一个数,等于上一行最后一个数。

  • 相关阅读:
    [转]OLAP的12条准则
    这几年
    方法论
    用NetHogs监控Linux每个进程的网络使用情况
    Centos下文本文件格式转码解决
    CentOS+Puppet分布式部署Zabbix监控系统
    ubuntu修复grub,u盘引导问题
    postfix搭建纯邮件转发服务器
    Mysql: 利用强制索引去掉重数据
    shell 变量赋值与替换
  • 原文地址:https://www.cnblogs.com/Zabreture/p/13460572.html
Copyright © 2011-2022 走看看