Fellow me on GitHub

HDU2643(SummerTrainingDay05-P 第二类斯特林数)

Rank

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 433    Accepted Submission(s): 207


Problem Description

Recently in Teddy's hometown there is a competition named "Cow Year Blow Cow".N competitors had took part in this competition.The competition was so intense that the rank was changing and changing.
Now the question is:
How many different ways that n competitors can rank in a competition, allowing for the possibility of ties. 
as the answer will be very large,you can just output the answer MOD 20090126.
Here are the ways when N = 2:
P1 < P2
P2 < P1
P1 = P2 
 

 

Input

The first line will contain a T,then T cases followed.
each case only contain one integer N (N <= 100),indicating the number of people.
 

 

Output

One integer pey line represent the answer MOD 20090126.
 

 

Sample Input

2 2 3
 

 

Sample Output

3 13
 

 

Author

teddy
 

 

Source

 

第二类Stirling数 S(p,k)

   

S(p,k)的一个组合学解释是:将p个物体划分成k个非空的不可辨别的(可以理解为盒子没有编号)集合的方法数。

k!S(p,k)是把p个人分进k间有差别(如:被标有房号)的房间(无空房)的方法数。

   

S(p,k)的递推公式是:S(p,k)=k*S(p-1,k)+S(p-1,k-1) ,1<= k<=p-1

边界条件:S(p,p)=1 ,p>=0    S(p,0)=0 ,p>=1

  

递推关系的说明:

考虑第p个物品,p可以单独构成一个非空集合,此时前p-1个物品构成k-1个非空的不可辨别的集合,方法数为S(p-1,k-1);

可以前p-1种物品构成k个非空的不可辨别的集合,第p个物品放入任意一个中,这样有k*S(p-1,k)种方法。

 

为n个队员分配k个名次,k的取值为1到n。可将问题转化为将n个球正好放入k的不同的盒子,即为第二类斯特林数,因为k个盒子不同,存在k!个排列,所以为k!× S2[n][k],答案为sum(i!*S2[n][i]) | 1<=i<=k

 1 //2017-08-05
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <algorithm>
 6 #define ll long long
 7 
 8 using namespace std;
 9 
10 const int N = 110;
11 const int MOD = 20090126;
12 ll stir2[N][N], ans[N], factorial[N];
13 
14 void init(){
15     factorial[1] = 1;
16     for(int i = 2; i < N; i++)
17           factorial[i] = (factorial[i-1]*i)%MOD;
18     memset(stir2, 0, sizeof(stir2));
19     for(int n = 1; n < N; n++){
20         stir2[n][1] = 1;
21         stir2[n][n] = 1;
22         for(int k = 2; k < n; k++){
23             stir2[n][k] = stir2[n-1][k-1]+k*stir2[n-1][k];
24             stir2[n][k] %= MOD;
25         }
26     }
27 }
28 
29 int main()
30 {
31     int T, n;
32     init();
33     cin>>T;
34     while(T--){
35         cin>>n;
36         ll ans = 0;
37         for(int i = 1; i <= n; i++)
38               ans = (ans + factorial[i]*stir2[n][i]) % MOD;
39         cout<<ans<<endl;
40     }
41 
42     return 0;
43 }

 

posted @ 2017-08-05 22:16  Penn000  阅读(239)  评论(0编辑  收藏  举报