代码
#include <iostream>
using namespace std;
typedef long long int LL;
const int MAX = 26;
LL factorial[MAX];
LL wrongArrang[MAX];
LL combination(int n, int m) {
if(n-m<m){
m = n-m;
}
LL numerator = 1; //分子
LL denominator = 1; //分母
for(int i=0; i<m; i++){
numerator *= n-i;
denominator *= m-i;
}
return numerator/denominator;
}
void f() {
wrongArrang[0] = 1;
wrongArrang[2] = 1;
wrongArrang[3] = 2;
for(int i=4; i<MAX; i++) {
wrongArrang[i] = (wrongArrang[i-1] + wrongArrang[i-2]) * (i-1);
}
}
int main() {
f();
int n;
cin>>n;
while(n) {
LL ans = 0;
for(int m=0; m<n/2+1; m++) {
LL tmp = combination(n, m);
tmp *= wrongArrang[m];
ans += tmp;
}
cout<<ans<<endl;
cin>>n;
}
return 0;
}
注解
1、求组合数C(n, m):combination(n, m)函数。没有用阶乘,用阶乘会造成数字太大,溢出!
2、错排公式:f(n)=(f(n-1)+f(n-2))*(n-1)
3、答对一半及以上就算过关:因此错误个数从[0, n/2]枚举,将答案相加即可。