RPG的错排
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2068
题目大意:
有N个人对应N个名字,然后你去把每一个名字对应到每个人,只要求答对一半及以上就算是过关,问有多少组答案能让他过关。
思考过程:
一眼就发现是错排,从N个人当中选出M个,然后进行错排,M可以从 0 一直到 N / 2。
我还是wa了,因为一开始的时候没有考虑到M可以为0。如果M为0,即表示没有全部排错,为一组答案。
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<map> #include<queue> #include<stack> #include<vector> #include<set> #include<ctype.h> #include<algorithm> #include<string> #define PI acos(-1.0) #define maxn 1000 #define INF 1<<25 #define mem(a, b) memset(a, b, sizeof(a)) typedef long long ll; using namespace std; ll D[13]; ll C[26][26]; void init() { D[1] = 0, D[2] = 1; for (ll i = 3; i <= 13; i++) D[i] = (i - 1) * (D[i - 1] + D[i - 2]); C[1][0] = C[1][1] = 1; for (int i = 1; i <= 25; i++) C[i][0] = 1; for (ll i = 2; i <= 25; i++) for (ll j = 1; j <= i; j++) C[i][j] = C[i - 1][j] + C[i - 1][j - 1]; } int main () { int n; init(); while(~scanf("%d", &n) && n) { ll sum = 0; for (ll i = 1; i <= n / 2; i++) { sum += D[i] * C[n][i]; } sum += 1; cout<<sum<<endl; } return 0; }