题目大意:
对前N个正整数,求其中前M个数中有K个数在原位置的排列总数
ans=sum{(-1)^i*nCr(i,M-k)*(N-k-i)!} * nCr(M,M-k)
i=0..M-k
#include <cstdio>
#include <cstring>
#define mod 1000000007L
long long c[1001][1001];
long long ncr(long long n,long long r)
{
if(c[n][r]!=-1)
return c[n][r];
if(n<r)
{
c[n][r]=0;
return 0;
}
if(r==0||n==r)
{
c[n][r]=1;
return 1;
}
c[n][r]=c[n-1][r]%mod+c[n-1][r-1]%mod;
c[n][r]%=mod;
return c[n][r];
}
//求阶乘
long long f(long long n)
{
long long ans=1;
for(int i=1;i<=n;i++)
{
ans*=i;
ans%=mod;
}
return ans;
}
int main()
{
int T;
int n,m,k;
memset(c,-1,sizeof(c));
long long ans,t1,t2;
for(int i=0;i<1001;i++)
{
for(int j=0;j<1001;j++)
{
if(c[i][j]==-1)
{
ncr(i,j);
}
}
}
scanf("%d",&T);
for(int iii=1;iii<=T;iii++)
{
scanf("%d%d%d",&n,&m,&k);
ans=0;
for(int i=0;i<=m-k;i++)
{
t1=ncr(m-k,i)%mod;
t2=f(n-k-i)%mod;
t1=t1%mod*t2%mod;
t1%=mod;
ans+=mod;
if(i%2==0)
{
ans+=t1;
}
else
{
ans-=t1;
}
ans%=mod;
}
ans=((ans%mod)*(ncr(m,k)%mod))%mod;
printf("Case %d: %lld\n",iii,ans);
}
return 0;
}