斯特林数(Stirling数)

题目链接

3165. 第一类斯特林数
3166. 第二类斯特林数
3020. 建筑师

第一类斯特林数(无符号)性质

第一类Stirling数表示将 n 个不同元素构成 m 个圆排列的数目,记为 s(n,m)[nm]

递推式:s(n,m)=s(n1,m1)+(n1)×s(n1,m)
s(0,0)=1
s(n,0)=0
s(n,n)=1
s(n,1)=(n1)!
s(n,n1)=Cn2
s(n,2)=(n1)!i=1n11i
s(n,n2)=2Cn3+3Cn4
k=0ns(n,k)=n!

第二类斯特林数性质

第二类Stirling数实际上是集合的一个拆分,表示将n个不同的元素拆分成m个集合的方案数,记为S(n,m){nm}

递推式:S(n,m)=S(n1,m1)+m×S(n1,m)
通项公式:S(n,m)=1m!k=0m(1)kCmk(mk)n
S(n,0)=0n
S(n,1)=1
S(n,n)=1
S(n,2)=2n11
S(n,n1)=Cn2
S(n,n2)=Cn3+3Cn4
S(n,3)=12(3n1+1)2n1
S(n,n3)=Cn4+10Cn5+15Cn6

两类斯特林数的关系(置换性):

k=0n[nk]{km}=k=0n{nk}[km]

例题

3165. 第一类斯特林数

第一类斯特林数(斯特林轮换数)[nk] 表示将 n 个两两不同的元素,划分为 k 个非空圆排列的方案数。

现在,给定 nk,请你求方案数。

圆排列定义:圆排列是排列的一种,指从 n 个不同元素中取出 m1mn 个不同的元素排列成一个环形,既无头也无尾。两个圆排列相同当且仅当所取元素的个数相同并且元素取法一致,在环上的排列顺序一致。

输入格式

两个整数 nk

输出格式

输出一个整数表示划分方案数。

答案对 109+7 取模。

数据范围

1kn1000

输入样例:

3 2

输出样例:

3
  • 时间复杂度:O(nk)

代码

#include<cstdio> using namespace std; const int mod=1e9+7; int n,k; int s[1005][1005]; int main() { scanf("%d%d",&n,&k); s[0][0]=1; for(int i=1;i<=n;i++) for(int j=1;j<=k;j++) s[i][j]=(s[i-1][j-1]+1ll*(i-1)*s[i-1][j])%mod; printf("%d",s[n][k]); return 0; }

3166. 第二类斯特林数

第二类斯特林数(斯特林子集数){nk} 表示将 n 个两两不同的元素,划分为 k 个非空子集的方案数。

现在,给定 nk,请你求方案数。

输入格式

两个整数 nk

输出格式

输出一个整数表示划分方案数。

答案对 109+7 取模。

数据范围

1kn1000

输入样例:

3 2

输出样例:

3
  • 时间复杂度:O(nk)

代码

#include<cstdio> using namespace std; const int mod=1e9+7; int n,k; int S[1005][1005]; int main() { scanf("%d%d",&n,&k); S[0][0]=1; for(int i=1;i<=n;i++) for(int j=1;j<=k;j++) S[i][j]=(S[i-1][j-1]+1ll*j*S[i-1][j])%mod; printf("%d",S[n][k]); return 0; }

3020. 建筑师

Z 是一个很有名的建筑师,有一天他接到了一个很奇怪的任务:在数轴上建 n 个建筑,每个建筑的高度是 1n 之间的一个整数。

Z 有很严重的强迫症,他不喜欢有两个建筑的高度相同。

另外小 Z 觉得如果从最左边(所有建筑都在右边)看能看到 A 个建筑,从最右边(所有建筑都在左边)看能看到 B 个建筑,这样的建筑群有着独特的美感。

现在,小 Z 想知道满足上述所有条件的建筑方案有多少种?

如果建筑 i 的左(右)边没有任何建造比它高,则建筑 i 可以从左(右)边看到。

两种方案不同,当且仅当存在某个建筑在两种方案下的高度不同。

输入格式

第一行一个整数 T,代表 T 组数据。

接下来 T 行,每行三个整数 n,A,B

输出格式

对于每组数据输出一行答案 mod109+7

数据范围

1n50000,
1A,B100,
1T200000

输入样例:

2 3 2 2 3 1 2

输出样例:

2 1

解题思路

第一类斯特林数

以最高的建筑作为分界线,左右分别分为 A1B1 部分,设每一部分有 k 个建筑,除去该部分最高建筑外,有 (k1)! 种方案数,正好对应第一类斯特林数,即 s(n1,A1+B1),现在就差分配方案数,可从 A1+B1 个建筑中选出 A1 个建筑放在最高建筑的左边,即 CA+B2A1,故总的方案数为 s(n1,A+B2)×CA+B2A1

  • 时间复杂度:O(T+n×(A+B))

代码

#include<bits/stdc++.h> using namespace std; const int mod=1e9+7; int c[205][205],s[50005][205]; int T,n,A,B; void init() { for(int i=0;i<=200;i++) for(int j=0;j<=i;j++) if(!j)c[i][j]=1; else c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod; s[0][0]=1; for(int i=1;i<=50000;i++) for(int j=1;j<=200;j++) s[i][j]=(s[i-1][j-1]+1ll*(i-1)*s[i-1][j])%mod; } int main() { init(); for(scanf("%d",&T);T;T--) { scanf("%d%d%d",&n,&A,&B); printf("%d\n",1ll*c[A+B-2][A-1]*s[n-1][A+B-2]%mod); } return 0; }

__EOF__

本文作者acwing_zyy
本文链接https://www.cnblogs.com/zyyun/p/15463249.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   zyy2001  阅读(580)  评论(0编辑  收藏  举报
编辑推荐:
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示