错排简单点说就是给n个节点它们原来的位置为i,
然后让你把它们从新排列使得它们都不在它们原来的位置上。
错排递归公式:f(i) = (i - 1) * (f(i - 1) + f(i - 2)); i >= 4 (f(0) = 0, f(1) = 0, f(2) = 1, f(3) = 2);
而本题的解法是:组合 + 错排
由于要猜对一半以上,就是那从n个人中取出小于等于n / 2的人进行错排
因为最后要求的答案是能够通过的所有解,所以只要累加0 -> n / 2的所有错排数
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
#define clear(n,m) memset(n,m,sizeof(n))
using namespace std;
__int64 C(int n, int m)
{
if (m > n / 2)
m = n - m;
__int64 u = 1, d = 1;
for (int i = 1;i <= m;i++)
{
u *= (n - i + 1);
d *= i;
}
return u / d;
}
int main()
{
int n, d[14] = { 1,0,1 };
for (int i = 3;i < 14;i++)
{
d[i] = (i - 1)*(d[i - 1] + d[i - 2]);
}
while (cin >> n && n)
{
__int64 res = 0;
for (int i = 0;i <= n / 2;i++)
{
res += C(n, n - i)*d[i];
}
cout << res << endl;
}
return 0;
}