全错排直接用全错排公式 dp[i]=(i-1)*(dp[i-1]+dp[i-2])
部分错排先把那一部分看做全错排,然后从总的里面抽取部分
https://vjudge.net/problem/HDU-2049(部分错排)
#include <stdio.h>
#include <iostream>
using namespace std;
long long dp[55];
int N,M;
int main()
{
dp[1]=0;
dp[2]=1;
for(int i=3;i<21;i++)
- dp[i]=(i-1)*(dp[i-1]+dp[i-2])
;
int C;
scanf("%d",&C);
while(C--){
scanf("%d%d",&N,&M);
long long sum=1;
int s;
if(M>(N/2))
s=N-M;
else
s=M;
// cout<<s<<endl;
for(int i=1;i<=s;i++)
sum=sum*(N-i+1)/i;
// cout<<sum<<endl;
cout<<sum*dp[M]<<endl;
}
return 0;
}