斯特林数

OI WIKI

 

一.

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

1.

边界s[1...n][1] = 1;

递推式:s(n, k) = s(n-1, k-1) + k * s(n-1, k)

2.

for(int i = 1; i <= 100; i++){
        stli[i][1] = 1;
        stli[i][100] = 1;
        for(int j = 2; j < 100; j++){
            stli[i][j] = (stli[i-1][j-1] + (j*stli[i-1][j]))%Mod;
        }
    }
code

3.

例题1

#include<iostream>
using namespace std;
const long long mod = 20090126;
const int N = 110;
long long a[N], s[N][N];
int main()
{
    a[0] = 1;
    for(int i = 1; i <= N; i++)
        a[i] = a[i-1]*i % mod;
    for(int i = 1; i <= N; i++)
    {
        s[i][1] = 1;
        for(int j = 2; j <= N; j++)
        {
            s[i][j] = (s[i-1][j-1]+j*s[i-1][j]%mod) % mod;
        }
    }
    int t;
    scanf("%d", &t);
    while(t--)
    {
        int n;
        scanf("%d", &n);
        long long ans = 0;
        for(int i = 1; i <= n; i++)
            ans = (ans+s[n][i]*a[i]%mod)%mod;
        printf("%lld\n", ans);
    }
    return 0;
}
AC Code

 

 

 

二.

第一类斯特林数:s(n, k) ,表示将 n个两两不同的元素,划分为 k 个互不区分的非空轮换的方案数。

补充含义:圆排列,是把n个数中拿出k个数组成一个圆的种类数,则这里组成m个圆排列的意思是组成m个不同的圆的种类数;

所以这里是插入一个环的方案数是x(x为该环的元素个数,由于首尾相连,而不是x+1)

1.

递推式:s(n, k) = s(n-1, k-1) + (n-1)* s(n-1, k)

2.

s[0][0] = 1;
    for(int i = 1; i <= N-10; i++)
    {
        for(int j = 1; j <= N-10; j++)
        {
            s[i][j] = (s[i-1][j-1]+(i-1)*s[i-1][j]) % mod;
        }
    }
Code

3.

例题1

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
#define mod 1000000007
const int N = 2010;
long long s[N][N], c[N][N];
int main()
{
    memset(s, 0, sizeof(s));
    memset(c, 0, sizeof(c));
    //求c[n][k];
    for(int i = 0; i <= N-10; i++)
        c[i][0] = 1;
    //求stalin
    s[0][0] = 1;
    for(int i = 1; i <= N-10; i++)
    {
        for(int j = 1; j <= N-10; j++)
        {
            c[i][j] = (c[i-1][j]+c[i-1][j-1]) % mod;
            s[i][j] = (s[i-1][j-1]+(i-1)*s[i-1][j]) % mod;
        }
    }
    int t;
    scanf("%d", &t);
    while(t--)
    {
        int n, f, b;
        scanf("%d %d %d", &n, &f, &b);
        long long ans;
        if(f+b-2 <= n-1)
            ans = (s[n-1][f+b-2]*c[f+b-2][f-1])%mod;
        else ans = 0 % mod;//这一步可真是艹啊 
        printf("%lld\n", ans);
    }
    return 0;
}
AC Code

 

posted @ 2021-03-16 14:45  bear_xin  阅读(139)  评论(0)    收藏  举报