题意:n人赛马最终名次的种类数目除以10056的余数。
解题思路:
设共有i个人,每个名次有j个人。
f[i] = (C[i][j]*f[i-j])的总和;
代码:
#include <iostream>
#include <cstring>
using namespace std;
#define ms(a,b) memset(a,b,sizeof(a))
const int mod = 10056;
const int maxn = 40;
int dp[maxn];
int c[1010][1010];
int f[1010];
void init() {
c[1][0] = c[1][1] = 1;
for (int i = 2; i <= 1000; i ++) {
c[i][0] = 1;
for (int j = 1; j <= i; j ++) {
c[i][j] = (c[i-1][j]%mod + c[i-1][j-1]%mod)%mod;
}
}
ms(f,0);
f[0] = 0;
f[1] = 1;
for (int i = 2; i <= 1000; i ++) {
for (int j = i; j >=1; j--) {
f[i] += (c[i][j] * f[i-j]);
f[i] %= mod;
}
f[i] ++ ; // 由于所有人都在第一名的情况下,f[i-j] = f[0] = 0,并未加上,所以在这里补充。
f[i] %= mod;
}
}
int main() {
int t;
cin >> t;
init();
for (int kase = 1; kase <= t; kase ++ ) {
int n;
cin >> n ;
cout << "Case " << kase << ": " << f[n] << endl;
}
return 0;
}