递推,f[i = i个名次][j = 共有j个人] = 方案数。
对于新加入的第j个人,如果并列之前的某个名次,那么i不变,有i个可供并列的名次选择,这部分是f[i][j-1]*i,
如果增加了一个名次,那么之前有i-1个名次,i-1个名次之间有i个空,这部分是f[i-1][j-1]*i。
/********************************************************* * --------------Tyrannosaurus--------- * * author AbyssalFish * **********************************************************/ #include<bits/stdc++.h> using namespace std; typedef long long ll; const int mod = 10056; const int maxn = 1001; int f[maxn][maxn];//i个名次 j个人 int ans[maxn]; /* 思路二 看成多次选第一名有多少个人 */ //#define LOCAL int main() { #ifdef LOCAL freopen("in.txt","r",stdin); #endif //cout<<mod*mod<<endl; int T, n, kas = 0; scanf("%d",&T); f[0][0] = 1; for(int i = 1; i < maxn; i++){ for(int j = i; j < maxn; j++){ f[i][j] = (f[i-1][j-1]+f[i][j-1])*i; if(f[i][j] >= mod) f[i][j] %= mod; } } for(int j = 1; j < maxn; j++){ for(int i = 1; i <= j; i++){ //i <= j ans[j] += f[i][j]; } if(ans[j] >= mod) ans[j] %= mod; } while(T--){ scanf("%d",&n); printf("Case %d: %d ", ++kas, ans[n]); } return 0; }