第二类斯特林数表示把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组的话能有多少种可能。
分组的要求:
- 小组不能为空
- 每个同学都会且仅会属于一个小组
- 不同小组的人数不一定相同
输入格式
整数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]);
}