第一类斯特林数
问题描述
Stirling[n][k] 把 n 个人排成k 个圈,(圈内有序)共有多少种排法
Stirling(p,p)=1(p>=0),有p个人和P个圆圈,每个圆圈就只有一个人
Stirling(P,0)=0(P>=1)如果至少有1个人,那么任何安排都至少包含一个圆圈
Stirling(P,K)=(P-1)*S1(P-1,K)+S1(P-1,K-1)
p个人 K 个圈时
Stirling[P][K] = 拿出一个人单独成一圈,然后 剩下 P-1个人 K-1个圈 + P-1个人 K个圈然后把这个人插入到(剩下(P-1))任意一个人的左手边(P-1) * Stirling[P-1][K]
模板
typedef long long LL;
const int maxn = 10;
const int mod = 1e9+7;
LL Stirling[maxn + 5][maxn + 5];
void SolveStirling(){
memset(Stirling, 0, sizeof(Stirling));
Stirling[1][1] = 1;
Stirling[1][0] = 0;
for(int i = 2; i <= maxn; ++i){
for(int j = 1; j <= maxn; ++j){
Stirling[i][j] = (Stirling[i - 1][j - 1] + (i - 1) * Stirling[i - 1][j]) % mod;
}
}
}
第二类斯特林数
解决什么问题:n 个不同元素划分到 m 个集合
第二类斯特林数 Stirling2(n,m) 表示的是把 n 个不同元素划分到 m 个集合的方案数。
元素在哪些集合并不重要,唯一重要的是各集合里装的是什么,而不管哪个集合装了什么。
考虑将前 n 个正整数,{1,2,...,n} 的集合作为要被划分的集合,把 {1,2,...,n} 分到 m 个非空且不可区分的集合的划分有两种情况:
1) 第n个元素 自己单独在一个集合的划分,存在有 Stirling2(n-1,m-1) 种划分个数
2)第 n个元素 不单独自己在一个盒子的划分,存在有 m*Stirling2(n-1,m) 种划分个数
考虑第二种情况,n 不单独自己在一个盒子,也就是 n 和其他元素在一个集合里面,也就是说在没有放 n 之前,有 n-1 个元素已经分到了m 个非空且不可区分的盒子里面(划分个数为 Stirling2(n-1,m)),那么现在问题是把 n 放在哪个盒子里面,此时有 m 种选择,所以存在有 m*Stirling2(n-1,m)
综上,可得出第二类斯特林数定理: Stirling2(n,m)=m*Stirling2(n-1,m)+Stirling2(n-1,m-1) (1<=m<=n-1)
typedef long long LL;
const int maxn = 10;
const int mod = 1e9+7;
LL Stirling2[maxn][maxn];
void SolveS2(){
memset(Stirling2, 0, sizeof(Stirling2));
Stirling2[1][1] = 1;
for(int i = 2; i <= maxn; ++i){
for(int j = 1; j <= i; ++j){
Stirling2[i][j] = (Stirling2[i - 1][j - 1] + j * Stirling2[i - 1][j]) % mod;
}
}
}
大佬博客:斯特林函数