HDU - 2512 (斯特林数,贝尔数)

题目意思:给你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)

                                            (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

4.贝尔数,我用bell[n]表示,那么有             bell[n] = \sum_{i=0}^{n} S2(n,i)

 

注意,在这道题里,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.......

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值