递推
假设第一名有i人 ,即C(n,i) i∈[1,n] ,剩下n-i个人的名次有f(n-i)种可能性,只要对于每种排名,将i个人都放在并列第一就是一种新的排名
所以f(n)=∑f(n-1)*C(n,i);
对于这i个人不需要考虑剩下如处于第二第三的情况,因为f(n-i)中已经包含这种情况了
剩下就是计算C(n,m)的问题,使用公式c(n,m)=n!/[(n-m)!*m!] 肯定会溢出
所以采用递推式c(n,m)=c(n-1,m-1)+c(n-1,m)
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
const int M=10056;
int C[1005][1005],f[1005];
void GetC()
{for(int n=0;n<=1000;n++){C[n][0]=C[n][n]=1;for(int m=1;n&&m<n;m++)C[n][m]=(C[n-1][m]+C[n-1][m-1])%M;}
}void solve()
{GetC();f[0]=1;f[1]=1;f[2]=3;f[3]=13;for(int n=2;n<=1000;n++){int ans=0;for(int i=1;i<=n;i++)ans=(ans+C[n][i]*f[n-i])%M;f[n]=ans;}}
int main()
{int T,kase=0;solve();
// for(int i=1;i<=1000;i++) cout<<f[i]<<endl;cin>>T;while(T--){int n;cin>>n;printf("Case %d: %d\n",++kase,f[n]);}return 0;
}