递推——第二类斯特林数

第二类斯特林数表示把n个元素分成k个非空集合的方案数,集合内是无序的。

推导过程

分为两种情况。

第一种情况,如果前n−1个元素组成了k−1个非空集合,那么当前元素自成一个集合。

第二种情况,如果前n−1个元素组成了k个集合,那么当前的这个元素可以放进这k个集合中任意的一个。

公式:

S(n,k)=S(n−1,k−1)+S(n−1,k)∗k

例题:

计算一下如果把n个互不相同的同学分成k组的话能有多少种可能。

分组的要求:

  1. 小组不能为空
  2. 每个同学都会且仅会属于一个小组
  3. 不同小组的人数不一定相同

输入格式

整数n,k,表示把n个同学分成k个小组。

1≤n≤30001≤n≤3000,1≤k≤n1≤k≤n

输出格式

整数m,表示可行的分组方案数

数字有点大,请输出模1e9+9之后的结果。

样例输入

6 3

样例输出

90

例题:

助教刚好把问题的答案发给了不同的人,请问有多少种可能?

输入格式

整数n,表示给助教发问题的人数。

1≤n≤10000000

输出格式

整数m,表示恰好没有把每个人的答案发给本人的情况数

数字有点大,请输出模1e9+9之后的结果。

样例输入

5

样例输出

44

代码实现:

#include <stdio.h>
#include <stdlib.h>
long long mod = 1e9+9;

int main(){
    long long people, group;
    scanf("%lld %lld",&people,&group);

    long long arr[3005][3005];
    memset(arr,0,sizeof(arr));

    arr[1][1] = 1;
    for(int i = 2 ; i <= people; i ++){
        for(int j = 1; j <= i; j++){
            arr[i][j] = arr[i-1][j-1]+j*arr[i-1][j];	
            if(arr[i][j]>mod)arr[i][j] %= mod;
        }
    }
    printf("%lld",arr[people][group]);
}
原文地址:https://www.cnblogs.com/miaomiaolan/p/12608662.html