hdu 2068 RPG错排

第一次接触到错排的题目,错排简单点说就是给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的所有错排数

AC代码如下:

/* Author: ACb0y Date: 2010年9月7日10:55:53 Type: Water(math) ProblemId: hdu 2068 Result: 2927240 2010-09-07 10:52:40 Accepted 2068 0MS 212K 596 B C++ ACb0y */ #include typedef __int64 int64; int64 d[14] = {0, 0, 1, 2}; //求错排数 void init() { for (int i = 4 ; i < 14; i++) { d[i] = (i - 1) * (d[i - 1] + d[i - 2]); } } //求组合数 int64 C_n_m(int n, int m) { if (m == 0) { return 1; } int64 up = 1; int64 down = 1; for (int i = 0; i < m; i++) { up *= (n - i); down *= (i + 1); } return up / down; } int main() { int n; init(); #ifndef ONLINE_JUDGE freopen("2068.txt", "r", stdin); #endif while (scanf("%d", &n) != EOF && n) { int64 ans = 1; //从n个人中去i个人错排 for (int i = 0; i <= n / 2; i++) { ans += C_n_m(n, i) * d[i]; } printf("%I64d/n", ans); } }

 

你可能感兴趣的:(HDU)