题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2643
题意:
有n个个选手参赛,问排名有多少种情况(可以并列)。
题解:
简化问题:
将n个不同的元素放到i个有差别的盒子中,情况数为P(n,i),求∑P(n,i) (1<=i<=n)
再简化:
将n个不同的元素放到i个无差别的盒子中,情况数为S(n,i),求∑( S(n,i)*i! ) (1<=i<=n)
哇这是第二类Stirling数 ( ̄▽ ̄)~*
递推式:s(n,k) = s(n-1,k-1) + k*s(n-1,k)
AC Code:
1 // s(n,k) = s(n-1,k-1) + k*s(n-1,k) 2 // s(n,n) = 1 3 // s(n,0) = 0 4 // ans = sigma(s[n][i = 1 to n] * i!) 5 6 #include <iostream> 7 #include <stdio.h> 8 #include <string.h> 9 #define MAX_N 105 10 #define MOD 20090126 11 12 using namespace std; 13 14 int n,t; 15 long long s[MAX_N][MAX_N]; 16 long long sum[MAX_N][MAX_N]; 17 long long fact[MAX_N]; 18 19 void stirling() 20 { 21 memset(s,0,sizeof(s)); 22 for(int i=1;i<MAX_N;i++) 23 { 24 s[i][i]=1; 25 for(int j=1;j<i;j++) 26 { 27 s[i][j]=(s[i-1][j-1]+j*s[i-1][j])%MOD; 28 } 29 } 30 } 31 32 void cal_fact() 33 { 34 fact[0]=1; 35 for(int i=1;i<MAX_N;i++) 36 { 37 fact[i]=(fact[i-1]*i)%MOD; 38 } 39 } 40 41 int main() 42 { 43 stirling(); 44 cal_fact(); 45 cin>>t; 46 for(int cas=1;cas<=t;cas++) 47 { 48 cin>>n; 49 long long sum=0; 50 for(int i=1;i<=n;i++) 51 { 52 sum+=s[n][i]*fact[i]; 53 sum%=MOD; 54 } 55 cout<<sum<<endl; 56 } 57 }
时间: 2024-08-05 23:41:27