在组合数学,Stirling 数可指两类数,第一类Stirling 数和第二类 Stirling 数,都是由18世纪数学家 James Stirling 提出的。
Stirling 数有两种,第一类和第二类Stirling 数
第一类斯特林数:
形如[ n m ] [ n m ] , 也写作 s ( n , k ) s ( n , k )
组合意义:
s ( n , k ) s ( n , k ) 表示吧n n 个数 分成k k 组 ,每组是一个环 ,求分成的方案数。
也就是一个轮子,怎么转都是一样的,如:1,2,3,4 和 4,1,2,3 只算一种 方案。
递推式:
s ( n + 1 , 2 ) = s ( n , 1 ) + s ( n , 2 ) ⋅ n s ( n + 1 , 2 ) = s ( n , 1 ) + s ( n , 2 ) ⋅ n
即要么自成一个环,要么加入其它k k 个环,可以插入n − 1 n − 1 个位置。(每两个数之间)
当然边界条件 [ 0 0 ] = 1 [ 0 0 ] = 1
性质:
1. s ( n , 1 ) = ( n − 1 ) ! s ( n , 1 ) = ( n − 1 ) !
2. s ( n , 2 ) = ( n − 1 ) ! × ∑ n − 1 i = 1 1 i s ( n , 2 ) = ( n − 1 ) ! × ∑ i = 1 n − 1 1 i
3. ∑ n i = 0 s ( n , k ) = n ! ∑ i = 0 n s ( n , k ) = n !
证明:
1. 显然,我们把n n 个元素排列起来,有n ! n ! 种可能,首尾相接即可得到一个环。这里面每种情况重复了n n 次,因为可以旋转n n 次,所以除以n n ,得到s ( n , 1 ) = ( n − 1 ) ! s ( n , 1 ) = ( n − 1 ) ! 。
2. 通过数学归纳法可以证明。
s ( n + 1 , 2 ) = s ( n , 1 ) + s ( n , 2 ) ⋅ n = ( n − 1 ) ! + n ( n − 1 ) ! n − 1 ∑ i = 1 1 i = ( n − 1 ) ! + n ! n − 1 ∑ i = 1 1 i = n ! n + n ! n − 1 ∑ i = 1 1 i = n ! n ∑ i = 1 1 i s ( n + 1 , 2 ) = s ( n , 1 ) + s ( n , 2 ) ⋅ n = ( n − 1 ) ! + n ( n − 1 ) ! ∑ i = 1 n − 1 1 i = ( n − 1 ) ! + n ! ∑ i = 1 n − 1 1 i = n ! n + n ! ∑ i = 1 n − 1 1 i = n ! ∑ i = 1 n 1 i
3. 这里有一个巧妙地“算两次”方法。 首先构造一个问题,求n n 个数的所有排列。 首先用乘法原理直接得出结论,a n s = n ! a n s = n ! 。 我们知道,对于一个排列对应一个置换,即:
( 1 2 . . . n a 1 a 2 . . . a n ) ( 1 2 . . . n a 1 a 2 . . . a n )
把这个置换中的上下对应位置连边,可以得到许多的环。由于排列和置换是一一对应的,所以我们要求排列的个数,就是求用n n 个元素组成环的方案数,所以我们枚举环的个数:
n ! = n ∑ k = 1 s ( n , k ) n ! = ∑ k = 1 n s ( n , k )
由于我们有s ( n , 0 ) = 0 s ( n , 0 ) = 0 ,所以也可以写成:
n ∑ k = 0 s ( n , k ) = n ! ∑ k = 0 n s ( n , k ) = n !
第二类斯特林数:
形如{ n k } { n k } , 也写作 S ( n , k ) S ( n , k )
组合意义:
S ( n , k ) S ( n , k ) 表示吧n n 个数分成k k 组,组内无序 ,每组没有区别 。
递推式:
{ n k } = { n − 1 k − 1 } + { n − 1 k } ∗ k { n k } = { n − 1 k − 1 } + { n − 1 k } ∗ k
即要么自成一个组,要么加入其它k k 个组,可以插入k k 个组。
当然边界条件{ 0 0 } = 1 { 0 0 } = 1
性质:
没有什么特别常用的。
通项公式:
S ( n , m ) = 1 m ! m ∑ k = 0 ( − 1 ) k C k m ( m − k ) n S ( n , m ) = 1 m ! ∑ k = 0 m ( − 1 ) k C m k ( m − k ) n
大概就是容斥原理,k k 枚举有多少个集合是空的,每种情况有C k m C m k 种空集情况,n n 个元素可以放进非空的m − k m − k 个集合中。这样求出来的答案是有序的,所以我们除以m ! m ! 使得其变为无序。
卷积形式:
它具有卷积的形式 { n m } = m ∑ k = 0 ( − 1 ) k k ! ( m − k ) n ( m − k ) ! { n m } = ∑ k = 0 m ( − 1 ) k k ! ( m − k ) n ( m − k ) !
可以用FFT在O ( m log 2 m ) O ( m log 2 m ) 的时间内算出{ n 1 } ⋯ { n m } { n 1 } ⋯ { n m }
转化幂:
第二类斯特林数可以用于转化幂:x n = n ∑ k = 1 { n k } x k – – x n = ∑ k = 1 n { n k } x k _ ,可以用归纳法证明
x n = x n − 1 ∑ k = 1 { n − 1 k } x k – – = n − 1 ∑ k = 1 { n − 1 k } ( x k + 1 – ––– – + k x k – – ) = n ∑ k = 1 { n − 1 k − 1 } x k – – + n ∑ k = 1 { n − 1 k } k x k – – = n ∑ k = 1 { n k } x k – – x n = x ∑ k = 1 n − 1 { n − 1 k } x k _ = ∑ k = 1 n − 1 { n − 1 k } ( x k + 1 _ + k x k _ ) = ∑ k = 1 n { n − 1 k − 1 } x k _ + ∑ k = 1 n { n − 1 k } k x k _ = ∑ k = 1 n { n k } x k _
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理