直接运用容斥原理,组合数学,P100,机械工业出版社
补一下维基百科的:http://zh.wikipedia.org/wiki/%E6%8E%92%E5%AE%B9%E5%8E%9F%E7%90%86 百度简直是渣渣-_-不过维基上的应该给出的时一个推论,我们要运用它原来的公式
不过有个地方要注意的就是 a = ( a + b + MOD )% MOD,当a可能为小数的时候,一定要加一个MOD之后再取余
AC代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
#define MOD 1000000007L
long long dp[1010][1010];
long long combination( int n, int k ){//组合
if( dp[n][k] != -1 ){
return dp[n][k];
}
if( k == 0 || n == k ){
return dp[n][k] = 1;
}
if( n < k ){
return dp[n][k] = 0;
}
return dp[n][k] = ( combination( n - 1, k - 1 ) % MOD + combination( n - 1, k ) % MOD ) % MOD;
}
long long factorial( long long n ){//阶乘
long long ans = 1;
for( int i = 1; i <= n; i++ ){
ans = ( ( ans % MOD ) * ( i % MOD ) ) % MOD;
}
return ans;
}
long long f( long long a, int b ){//a的b次方
long long ans = 1;
for( int i = 1; i <= b; i++ ){
ans *= a;
}
return ans;
}
int main(){
int T, Case = 1;
int N, M, K;
long long ans = 1;
memset( dp, -1, sizeof( dp ) );
for( int i = 1000; i >= 1; i-- ){
for( int j = 1000; j >= 1; j-- ){
if( dp[i][j] == -1 ){
combination( i, j );
}
}
}
cin >> T;
while( T-- ){
cin >> N >> M >> K;
ans = 0;
for( int i = 0; i <= M - K; i++ ){
long long temp1 = combination( M - K, i ) % MOD;
long long temp2 = factorial( N - K - i ) % MOD;
long long temp3 = ( temp1 * temp2 ) % MOD;
if( i % 2 == 0 ){
ans = ans + temp3 + MOD;
}else{
ans = ans - temp3 + MOD;
}
ans %= MOD;
}
ans = ( ans % MOD ) * ( combination( M, K ) % MOD ) % MOD;
cout << "Case " << Case++ << ": " << ans << endl;
}
return 0;
}