Question link:
Http://acm.hdu.edu.cn/showproblem.php? PID = 1, 4489
Question meaning:
To give N, find n tall and short people in a row to sort the numbers in ascending order.
Solution:
Combine DP.
For N people, set their heights to 1, 2, 3, and N.
For the nth person, assume that the first n-1 person has been put. The Nth person has n positions to put. For any position J, the height N of the nth person is obviously greater than that of the first n-1 person. So the n-person's J-1 on the left
In, the last person must be satisfied by dropping his height. In the n-J person on the right, the person who started to get the person behind him by raising his height, of course front J-1 personal optional c (n-1, J-1 ).
Therefore, when the DP [I] [0] State is set, it indicates that there is one person, and the first person obtains the total number of groups of the second person by increasing the number. The height of the first person must be different, so only the number is considered.
DP [I] [1] indicates that one person exists and the last person is obtained by dropping.
Obviously, when the number of people is the same, based on the symmetry, DP [I] [0] = DP [I] [1] = sum [I]/2 sum [I] is the total number of I individual's compliant orders.
For nth person put to location J, there are C (n-1, J-1) * DP [J-1] [0] * DP [n-J] [1] cases.
Code:
# Include <iostream> # include <cstdio> # include <cstring> # include <cmath> # include <algorithm> # include <cstdlib> # include <cctype> # include <map> # include <set> # include <queue> # include <vector> using namespace STD; const double EPS = 1e-5; const double Pi = ACOs (-1.0); typedef _ int64 ll; ll DP [30] [2]; ll sum [30]; ll CAL (int A, int B) // find the cab can actually be calculated by recursion, cab = C (A-1) (b-1) + C (A-1) B {If (B = 0) return 1; ll res = 1; for (INT I = 0; I <B; I ++) {res * = (a-I) ;}for (INT I = 1; I <= B; I ++) RES/= I; return res ;} int main () {DP [0] [0] = DP [0] [1] = 1; DP [1] [0] = DP [1] [1] = 1; sum [1] = 1; for (INT I = 2; I <= 20; I ++) {sum [I] = 0; For (Int J = 1; j <= I; j ++) {sum [I] + = (DP [J-1] [0] * DP [I-j] [1] * CAL (I-1, j-1);} DP [I] [0] = DP [I] [1] = sum [I]/2; // By symmetry // printf ("I: % d % i64d \ n ", I, sum [I]);} // printf (" % d % i64d \ n ", 20, sum [20]); int t; int D, K; scanf ("% d", & T); While (t --) {scanf ("% d", & D, & K); printf ("% d % i64d \ n", D, sum [k]);} return 0 ;}