这道题与以往的递归不太一样,首先递归式子包括组合数,基本第归式是C(m,nf(n)。f(n)为n个人的全错排,全错排可以理解为所有的排列,然后减去反面的情况。即,一个人排对的情况,两个人排对的地方....全排对的情况.。这个可以用公式C(n,m)*right(n-m)(m取1...n)递归得出。然后递归的函数也与以前打的不一样内部含有一个循环。
#include<cstdio>
using namespace std;
int c,n,m;
long long O(int n){
if(n==1)
return 1;
return n*O(n-1);
}
long long A(int n,int m){///n>m
if(m==n)
return O(m);
return O(n)/O(n-m);
}
long long C(int n,int m){
return A(n,m)/O(m);
}
long long solve(int m){
if(m==2)
return 1;
long long sum=0;///sum要在里面定义,因为这个sum是对应一个人数时的反面的加和。
for(int i=1;i<m-1;i++)
sum+=C(m,i)*solve(m-i);
return O(m)-(sum+1);
}
int main(){
while(scanf("%d",&c)!=EOF){
for(int i=0;i<c;i++){
scanf("%d%d",&n,&m);
long long ans=C(n,m)*(solve(m));
printf("%lld\n",ans);
}
}
return 0;
}