一道和计数有关的组合数题。
题目大意
本题背景是赛马,给出T组数据,每组一个n,代表n匹马,要求出可能的排名情况(可能并列)。
分析
设有x(k)代表n=k时的方案数,设第一名有y头马,故其方案书为C(n,y)*x(k-y)。递推可解出答案,时间为0ms。
注意
1.需预先处理出组合数,否则会T。
2.注意当k=0时,方案数为0.
上代码
#include<bits/stdc++.h> using namespace std; int al[1001][1001],bl[1001],T; int M=10056; long long cl(long long a){ if(a<=1) return 1; int ans=0; for(int i=1;i<=a;i++){ if(!bl[a-i]) bl[a-i]=cl(a-i)%M; ans+=(al[a][i]*bl[a-i]%M); } return ans; } void cl1(){ for(int i=1;i<=1000;i++) al[i][0]=al[i][i]=1; for(int i=2;i<=1000;i++) al[i][i-1]=al[i][1]=i; for(int i=4;i<=1000;i++) for(int j=2;j<i-1;j++) if(!al[i][j]) al[i][i-j]=al[i][j]=(al[i-1][j-1]+al[i-1][j])%M; } int main(){ memset(al,0,sizeof(al)); memset(bl,0,sizeof(bl)); cl1(); int t=0,n; scanf("%d",&T); bl[0]=0; while(T--){ scanf("%d",&n); if(!bl[n]) bl[n]=cl(n)%M; printf("Case %d: %d\n",++t,bl[n]%M); } return 0; }