数学专项counting:UVa 11481
2013-10-16 23:12
447 查看
题目大意就是求N个数的排列中有多少个前M个数恰有M-K个错牌。这里可以先从前M个数中选K个数不变,即C(M,K)种。然后问题就转化为求n个数前m个数错排的排列数。
递推方程为:f[i][j]=(i-j)*f[i-1][j-1]+(j-1)*f[i-1][j-2];
边界条件为:f[i][0]=i!。
递推方程为:f[i][j]=(i-j)*f[i-1][j-1]+(j-1)*f[i-1][j-2];
边界条件为:f[i][0]=i!。
#include <iostream> #include <cstdio> #include <cstring> using namespace std; typedef long long LL; const LL mod=1000000007; const int maxn=1010; LL C[maxn][maxn],dp[maxn][maxn]; void init() { memset(C,0,sizeof(C)); memset(dp,0,sizeof(dp)); C[0][0]=1; for(int i=0;i<=1000;i++) { C[i][0]=C[i][i]=1; for(int j=1;j<i;j++) C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod; } dp[0][0]=1; dp[1][0]=1;dp[1][1]=0; for(int i=2;i<=1000;i++) { dp[i][0]=dp[i-1][0]*i%mod; for(int j=1;j<=i;j++) { dp[i][j]=(dp[i][j]+(i-j)*dp[i-1][j-1])%mod; if(j>=2) dp[i][j]=(dp[i][j]+(j-1)*dp[i-1][j-2])%mod; } } } int main() { //freopen("in.txt","r",stdin); init(); int T,kase=1; int n,m,k; scanf("%d",&T); while(T--) { scanf("%d%d%d",&n,&m,&k); printf("Case %d: %lld\n",kase++,C[m][k]*dp[n-k][m-k]%mod); } return 0; }
相关文章推荐
- 数学专项counting:UVa 580
- 数学专项counting:UVa 417
- 数学专项counting:UVa 11529
- 数学专项counting:UVa 11038
- 数学专项counting:UVa 10883
- 数学专项counting:UVa 10237
- 数学专项counting:UVa 10128
- 数学专项counting:UVa 10079
- 数学专项counting:UVa 10081
- 数学专项number_theory:UVa 10951
- 数学专项number_theory:UVa 10368
- 数学专项counting:LA 3720
- Triangle Counting+uva+数学题
- 数学专项matrix:UVa 11551
- 数学专项game_theory:UVa 12293
- 数学专项matrix:UVa 10689
- 数学专项game_theory:UVa 11892
- 数学专项number_theory:UVa 10539
- 数学专项counting:LA 3295
- 数学专项number_theory:UVa 11105