概述

斯特林数(Stirling Numbers) 是一类重要的组合数,用于描述集合的划分和排列的结构关系。1

主要有两类:

  • 第一类斯特林数:将 个元素排成 个非空轮换
  • 第二类斯特林数:将 个元素划分成 个非空集合

第一类斯特林数(Stirling Numbers of the First Kind)

定义

记作 \left[\begin{n}\\k\end{array}\right],表示将 个不同元素排成 个**非空轮换(Cycle)**的方案数。

轮换:环形排列,如 是同一个轮换。

递推关系

含义:

  • 新元素单独成一个轮换:
  • 新元素插入已有轮换的任意位置:

性质

  • (当

第二类斯特林数(Stirling Numbers of the Second Kind)

定义

记作 \left\{\begin{n}\\k\end{array}\right\},表示将 个不同元素划分成 个**非空集合(Subset)**的方案数。

递推关系

含义:

  • 新元素单独成一个集合:
  • 新元素加入已有 个集合中的任意一个:

封闭形式

这是容斥原理的应用。

贝尔数(Bell Numbers)

定义

贝尔数 表示将 个元素划分成任意数量非空集合的方案数:

递推关系(Dobinski公式)

性质

计算方法

O(nk) 动态规划

// 第一类斯特林数
vector<vector<long long>> stirling1(int n) {
    vector<vector<long long>> s(n+1, vector<long long>(n+1, 0));
    s[1][1] = 1;
    for (int i = 2; i <= n; i++) {
        for (int k = 1; k <= i; k++) {
            s[i][k] = (s[i-1][k-1] + (i-1) * s[i-1][k]) % MOD;
        }
    }
    return s;
}
 
// 第二类斯特林数
vector<vector<long long>> stirling2(int n) {
    vector<vector<long long>> S(n+1, vector<long long>(n+1, 0));
    S[1][1] = 1;
    for (int i = 2; i <= n; i++) {
        for (int k = 1; k <= i; k++) {
            S[i][k] = (S[i-1][k-1] + k * S[i-1][k]) % MOD;
        }
    }
    return S;
}

O(n log n) 使用多项式

第二类斯特林数可以通过多项式求幂在 内计算一行:

应用场景

1. 排列分解

个元素的排列分解成 个轮换,第一类斯特林数给出方案数。

的排列可以分解为:

  • 1个轮换:
  • 2个轮换:
  • 3个轮换:

2. 集合划分计数

个任务分配给 个工人(工人不可区分),方案数为

3. 与其他数列的关系

  • 阶乘
  • 贝尔多项式:指数生成函数与贝尔多项式相关

对照表

(第一类) (第二类)
1
2
3
4

参考


Last updated: 2026-04-06

Footnotes

  1. 本内容参考 OI-Wiki 斯特林数,内容经过验证和扩展。