这个题应该也可以用递推来做(LRJ白书上这么写的,但是我不会),我用了容斥原理。
公式是ans=C(m,k)*【(n-k)!-C(m-k,1)*(n-k-1)!+C(m-k,2)*(n-k-2)!-……+(-1)^i*C(m-k,i)*(n-k-i)!】其中i的范围是【0,m-k】
这个公式用排除法很好想到,但是我却因为不会求组合数不会模运算折腾了好长时间。。。
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define MAXN 1005
#define MOD 1000000007
#define INF 2139062143
#define EPS (1e-8)
#define ll long long
using namespace std;
ll C[MAXN][MAXN],Fac[MAXN];
void Init()
{
Fac[0]=1;
for(int i=1; i<=1000; ++i)
{
ll res=Fac[i-1]*i;
Fac[i]=res%MOD;
}
for(int i=0; i<=1000; ++i)
for(int j=0; j<=1000; ++j)
C[i][j]=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;
}
}
int main()
{
Init();
int T,kase=0;
scanf("%d",&T);
while(T--)
{
int m,n,k;
scanf("%d%d%d",&n,&m,&k);
ll ans=Fac[n-k];
for(int i=1; i<=m-k; ++i)
{
ll res=C[m-k][i]*Fac[n-k-i]%MOD;
if(i%2) ans=ans-res;
else ans=ans+res;
ans=ans%MOD;
if(ans<0) ans=ans+MOD;
}
ans=ans*C[m][k]%MOD;
printf("Case %d: %lld\n",++kase,ans);
}
return 0;
}