HDU2643 Rank 第二类斯特林数

xiaoxiao2021-02-28  52

第二类斯特林数

把一个包含n个元素的集合分成k个非空子集的方法数: 初始值: S2(n,0)=0,S2(n,k)=0(n<k) S2(n,1)=S2(n,n)=1 递推式: S2(n,k)=S2(n1,k1)+S2(n1,k)k

考虑第n个元素,如果它自成一个集合,那么前n-1个元素构成k-1个集合,就是S(n,k),如果它不是自成集合,那么前面n-1个元素构成k个集合,再把第n个元素加到任意一个集合中,共k种方案。 题目大意: n位选手参加比赛,每个选手有一个排名,有可能有并列,那么排名情况有多少种可能? n位选手可以放到1个集合,两个集合。。。。n个集合,因为每个集合对应的是名次,所以集合是区分的。 那么对于n个选手,可以选择的方案数: ni=1S2,(n,i)i!

#include <bits/stdc++.h> using namespace std; const int mod = 20090126; const int MAXN = 100+5; int n; int s2[MAXN][MAXN]; int fac[MAXN]; void get_s2() { fac[0] = 1; for(int i = 1; i <= 100; ++i)fac[i] = (long long)fac[i-1]*i%mod; for(int i = 1; i <= 100; ++i) { s2[i][1] = s2[i][i] = 1; for(int j = 2; j < i; ++j) { s2[i][j] = (s2[i-1][j-1] + (long long)j*s2[i-1][j]%mod)%mod; } } } int main() { get_s2(); int t; scanf("%d",&t); while(t--) { scanf("%d",&n); int ans = 0; for(int i = 1; i <= n; ++i)ans = (ans+(long long)fac[i]*s2[n][i]%mod)%mod; printf("%d\n",ans); } return 0; }
转载请注明原文地址: https://www.6miu.com/read-200081.html

最新回复(0)