My train of thought is this:
Enumerate the correct number I, then select the I position from n positions, C (n,i)
So the rest of the n-i position is not the answer, we temporarily become a dislocation arrangement
Now the difficulty is, how to arrange the ball dislocation
Set F[i] Represents the number of I digits, the type of dislocation arranged
Then, only consider the first i-1 number dislocation arrangement, temporarily put the number I position in the first place, at this time is not legal because I position I can not put I, so consider the I and other numbers to replace the position
In the first i-1 position, select a position, the position of the number and the number I exchange position, the possible situation is (I-1) *f[i-1]
It seems that the situation has all been considered, in fact, there is a situation not considered.
If the former i-1 position, there is a position k, put the number k, and then the other I-2 numbers are misaligned arrangement, then as long as the number k and the number I exchange, but also to make the newly generated permutation is misaligned arrangement
This is not the case in the first case. The type of this condition has the position of the enumeration K * I-2 digits of the dislocation permutation, i.e. (i-1) *f[i-2]
Sum up
f[i]= (i-1) * (F[i-1]+f[i-2])
where the boundary f[1]=0,f[2]=1
So the problem is basically done ~
#include <map> #include <set> #include <cmath> #include <stack> #include <queue> #include <cstdio> #include <string> #include <vector> #include <cstring> #include <iostream># Include<algorithm> #include <functional>using namespace std;typedef long long ll;typedef pair<int, int > pii;const int MX = 28 + 5; LL F[MX]; LL C[mx][mx];int Main () { f[0] = 1; F[1] = 0; F[2] = 1; for (int i = 3; i < MX; i++) { F[i] = (F[i-1] + f[i-2]) * (i-1); } C[0][0] = 1; for (int i = 1; i < MX; i++) { c[i][0] = c[i][i] = 1; for (int j = 1; j < I; J + +) { c[i][j] = c[i-1][j-1] + c[i-1][j]; } } int n; while (~SCANF ("%d", &n), n) { LL ans = 0; for (int i = (n + 1)/2; I <= n; i++) { ans + = c[n][i] * f[n-i]; } printf ("%i64d\n", ans);} }
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Combinatorial math + recursive hdu2068 RPG in the wrong row