贝尔数
贝尔数是以埃里克·坦普尔·贝尔命名,是组合数学中的一组整数数列,开首是(OEIS的A000110数列):
$$B_0 = 1, B_1 = 1, B_2 = 2, B_3 = 5, B_4 = 15, B_5 = 52, B_6 = 203, ...$$
$B_n$ 的含义是基数为 $n$ 的集合划分成非空集合的划分数。
例如, $B_3=5$ 是因为3个元素的集合有5种划分方法:
{{a}, {b}, {c}}
{{a}, {b, c}}
{{b}, {a, c}}
{{c}, {a, b}}
{{a, b, c}};
贝尔数有递推公式:
$$displaystyle B_{n+1} = sum_{k=0}^ninom{n}{k}B_k$$
上述组合公式的证明:
可以这样来想,$B_{n+1}$ 是含有 $n+1$ 个元素集合的划分个数,考虑元素 $b_{n+1}$,
假设他被单独划分到一类,那么还剩下n个元素,这种情况下划分个数为 $inom{n}{n}B_n$
假设他和某一个元素被划分为一类,那么还剩下n-1个元素,这种情况下划分个数为 $inom{n}{n-1}B_{n-1}$
假设他和某两个元素被划分为一类,那么还剩下n-2个元素,这种情况下划分个数为 $inom{n}{n-2}B_{n-2}$,
依次类推,得到了上述组合公式
它们也适合“Dobinski公式”:
$displaystyle B_n = frac{1}{e}sum_{k=0}^{infty}frac{k^n}{k!}$
即期望值为1 的泊松分布的 $n$ 次矩。
它们也适合"Touchard同余":若 $p$ 是任意素数,那么
$$B_{p+n} = B_n + B_{n+1}$$
$$B_{p^m+n} = mB_n + B_{n+1}$$
贝尔数模素数 $p$ 的周期为:
$$T_p = frac{p^p-1}{p-1}$$
每个贝尔数都是相应第二类斯特林数的和
$$displaystyle B_n = sum_{k=0}^nS(n, k)$$
因为,第二类斯特林数 $S(n, k)$ 是把基数为 $n$ 的集合划分为正好 $k$ 个非空集合的方案数。
此外,贝尔数的指数型母函数是
$$displaystyle sum_{n=0}^{infty }frac{B_n}{n!}x^n = e^{e^x-1}$$
贝尔三角形
用以下方法建构一个三角矩阵(形式类似杨辉三角形):
- 第一行第一项为1($a_{1,1}=1$)
- 对于 $n>1$,第 $n$ 行第一项等于第 $n-1$ 项的最后一项($a_{n,1} = a_{n-1, n-1}$)
- 对于 $m,n>1$,第 $n$ 行第 $m$ 项等于它左边和左上两个数之和($a_{n,m} = a_{n, m-1} + a_{n-1, m-1}$)
结果如下:(OEIS:A011971)
每行首项是贝尔数。每行之和是第二类Stirling数。
可以利用这个三角形来求Bell数,
#include<bits/stdc++.h> using namespace std; const int maxn = 2000+5; const int mod = 3; //周期为13 int bell[maxn], T[maxn]; void Bell(int n, int mod) //求前n项Bell数 { bell[0] = bell[1] = 1; T[0] = 1;T[1] = 2; for(int i = 2;i <= n;i++) { T[i-1] = bell[i-1]; for(int j = i-2;j >= 0;j--) //滚动数组 T[j] = (T[j] + T[j+1]) % mod; bell[i] = T[0]; } } int main() { Bell(2000, mod); for(int i = 0;i < 100;i++) printf("%d%c", bell[i], (i+1)%13 == 0 ? ' ' : ' '); }
参考链接:
1. https://zh.wikipedia.org/w/index.php?title=%E8%B4%9D%E5%B0%94%E6%95%B0
2. https://blog.csdn.net/ACdreamers/article/details/12309269