题目意思:给你n个数,让你组成从1~n个不重集合的组合数目是多少?
题解思路:
知识点:组合数学中的第二斯特林数,贝尔数
前提:
1.有一种组合数叫做“斯特林数”,它有两种类型,分别为第一类斯特林数和第二类斯特林数。
2.其中,第一类斯特林数,简写为 [n, k] 表示把n个不同的数字组成k个圆圈的组合数目(只要这k个圆圈不能够通过旋转得到相同的状况就算一种组合),函数用S1(n,k)表示。
2.1递推式为S1(n,k)=S1(n-1,k-1)+ (n-1)*S1(n-1,k)
2.2求解方法有以下两种:(1)母函数+FFT,O(nlog2n),母函数为 ![\prod_{i=0}^{n-1}(x+i)](https://private.codecogs.com/gif.latex?%5Cdpi%7B150%7D%20%5Cprod_%7Bi%3D0%7D%5E%7Bn-1%7D%28x+i%29)
(2) DP递推系数
3.还有一种斯特林数,简写为 {n,k} 表示把n个不同的数字组成k个集合的组合数目,
函数用S2(n,k)表示
3.1递推式为S2(n,k)=S2(n-1,k-1) + k* S2(n-1,k)
3.2求解方法(无法使用母函数)(1)但是可以容斥原理+卷积+FFT,O(nlog2n)
(2)S2(n,k) = ![\frac{1}{k!}\sum_{i=0}^{k}(-1)^i\binom{k}{i}(k-i)^n](https://private.codecogs.com/gif.latex?%5Cdpi%7B150%7D%20%5Cfrac%7B1%7D%7Bk%21%7D%5Csum_%7Bi%3D0%7D%5E%7Bk%7D%28-1%29%5Ei%5Cbinom%7Bk%7D%7Bi%7D%28k-i%29%5En)
4.贝尔数,我用bell[n]表示,那么有 ![bell[n] = \sum_{i=0}^{n} S2(n,i)](https://private.codecogs.com/gif.latex?%5Cdpi%7B150%7D%20bell%5Bn%5D%20%3D%20%5Csum_%7Bi%3D0%7D%5E%7Bn%7D%20S2%28n%2Ci%29)
注意,在这道题里,i要从1开始,接下只要先求S2(0,0)~S2(2000,2000), 之后逐次累加到bell[n]即可
#include<bits/stdc++.h>
#define register int rint
#define INF 0x3f3f3f3f3f
#define MOD 1000000007
#define mem(a,b) memset(a,b,sizeof(a))
#define PI 3.141592653589793
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int>PII;
const int N=2020;
const int Max=1e4+20;
const double esp=1e-6;
inline int rd() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int n,t;
int bell[N],s2[N][N];
int main()
{
t=rd();
mem(s2,0);
s2[0][0]=1;
for(int i=1;i<=2000;++i) s2[i][1]=1;
for(int i=2;i<=2000;++i)
{
for(int j=2;j<=i;++j)
s2[i][j]=(s2[i-1][j-1]+j*s2[i-1][j])%1000;
}
while(t--)
{
n=rd();
bell[0]=0;
for(int i=1;i<=n;++i) bell[i]=(bell[i-1]+s2[n][i])%1000;
cout<<bell[n]<<endl;
}
}
参考博客:https://blog.csdn.net/litble/article/details/80882581
备注:一开始提交的时候碰到了内存超限,我又重新更改了一下,顺便写一下内存的求公式:
假设申请了 int a[x][x],那么你的内存为y(mb) = x*x*4/1024/1024
一个int 等于 4个字节,一个字节等于一个byte,1kb=1024byte,1mb=1021kb.......