HDU 2643 Rank:第二类Stirling数

题目链接: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 }
原文地址:https://www.cnblogs.com/Leohh/p/7384261.html