题意:
求n个数的排列,前m个中有k个在自己的位置上的方法数。
思路:
设D[n]为n个元素的错排数.
于是我们有D[1] = 0 D[2] = 1;
D[n] = (D[n-1] + D[n-2]) * (i-1)
考虑问题本身,我们首先从前m个数选k个数不动.即C(m,k)。对于没有选的前m中的m-k个数肯定是参与了错排,而后面n-m个数中参加错排的个数不定,所以我们枚举一个后面n-m个数中选出i(0 <= i <= n - m)个数有没有参与错排。总共就有n-k-i参与了错排.
综上所述,ans公式就是C[m][k] * sigama(C[n-m][i] * D[n-k-i]) % mod;
预处理出组合数和错排数,然后就乱搞了。
注意有个坑点。。D[0]要赋值为1
参考code:
/*
#pragma warning (disable: 4786)
#pragma comment (linker, "/STACK:0x800000")
*/
#include <cassert>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <string>
#include <vector>
#include <list>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <algorithm>
#include <iterator>
#include <utility>
using namespace std;
template< class T > T _abs(T n){
return (n < 0 ? -n : n);
}
template< class T > T _max(T a, T b){
return (!(a < b) ? a : b);
}
template< class T > T _min(T a, T b){
return (a < b ? a : b);
}
template< class T > T sq(T x){
return x * x;
}
template< class T > T gcd(T a, T b){
return (b != 0 ? gcd<T>(b, a%b) : a);
}
template< class T > T lcm(T a, T b){
return (a / gcd<T>(a, b) * b);
}
template< class T > bool inside(T a, T b, T c){
return a<=b && b<=c;
}
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define F(i, n) for(int (i)=0;(i)<(n);++(i))
#define rep(i, s, t) for(int (i)=(s);(i)<=(t);++(i))
#define urep(i, s, t) for(int (i)=(s);(i)>=(t);--(i))
#define repok(i, s, t, o) for(int (i)=(s);(i)<=(t) && (o);++(i))
#define MEM0(addr) memset((addr), 0, sizeof((addr)))
#define MP(x, y) make_pair(x, y)
#define REV(s, e) reverse(s, e)
#define SET(p) memset(pair, -1, sizeof(p))
#define CLR(p) memset(p, 0, sizeof(p))
#define MEM(p, v) memset(p, v, sizeof(p))
#define CPY(d, s) memcpy(d, s, sizeof(s))
#define READ(f) freopen(f, "r", stdin)
#define WRITE(f) freopen(f, "w", stdout)
#define SZ(c) (int)c.size(
#define PB(x) push_back(x)
#define ff first
#define ss second
#define ll long long
#define ld long double
#define pii pair< int, int >
#define psi pair< string, int >
#define ls l,mid,rt<<1
#define rs mid+1,r,rt<<1|1
#define debug(x) cout << #x << " = " << x << endl
const double PI = acos(-1.0);
const int inf = 1<<30;
const int maxn = 1000;
const int mod = 1000000007;
int m,n,k;
ll D[maxn+5];
ll C[maxn+5][maxn+5];
void init(){
C[0][0] = 1;
rep(i,1,maxn){
C[i][0] = C[i][i] = 1;
rep(j,1,i-1) C[i][j] = (C[i-1][j-1] + C[i-1][j]) % mod;
}
D[1] = 0,D[0] = D[2] = 1;
rep(i,3,maxn) D[i] = (i-1) * (D[i-1] + D[i-2]) % mod;
}
ll solve(int n,int m,int k){
ll ans = 0;
rep(i,0,n-m) ans = (ans + C[n-m][i] * D[n-k-i]) % mod;
return ans * C[m][k] % mod;
}
int main(){
//READ("in.txt");
int t,kase = 1;
scanf("%d",&t);
init();
while(t--){
scanf("%d%d%d",&n,&m,&k);
printf("Case %d: %llu\n",kase++,solve(n,m,k));
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-11-03 05:40:36