意义:n个不同的元素,每个元素都不在自己原来位置的排列方案数。
递推式:
通项:
代码:
void Init(){
d[0] = 1,d[1] = 0,d[2] = 1; //不要少了d[0]
for(int i=3;i<N;i++)
d[i] = (i-1) * (d[i-1] + d[i-2]);
}
lightoj1095:
题意:共n个数,前m个位置恰号有k个在自己的位置上。
题解:
-
在前m个选k个在自己的位置上,有种选法;
-
后面的(n-m)个数错排的个数不确定,所以我们以此枚举有i个数在自己位置上。
-
所以不在自己位置上的就是(n-k-i) 。
-
公式为
#include <bits/stdc++.h>
#define mod(x) ((x) % MOD)
using namespace std;
typedef long long ll;
int const MOD = 1e9 + 7;
int const N = 1000 + 10;
int n,m,k,T;
ll d[N],c[N][N];
void Init(){
d[0] = 1,d[1] = 0,d[2] = 1;
for(int i=3;i<N;i++)
d[i] = mod((i-1) * (d[i-1] + d[i-2]));
for(int i=0;i<N;i++){
c[i][i] = c[i][0] =1;
for(int j=1;j<i;j++)
c[i][j] = mod(c[i-1][j-1]+c[i-1][j]);
}
}
ll solve(){
ll ans = 0;
for(int i=0;i<=n-m;i++)
ans = mod(ans + mod(c[n-m][i] * d[n-k-i]));
return mod(ans * c[m][k]);
}
int main(){
Init();
scanf("%d",&T);
int caser = 0;
while(T--){
cin>>n>>m>>k;
printf("Case %d: %lld\n",++caser,solve());
}
return 0;
}