// Expressions (bracket expression) // PC/ultraviolet A IDs: 110604/10157, popularity: C, success rate: average level: 2 // verdict: accepted // submission date: 2011-06-03 // UV Run Time: 0.668 S // copyright (c) 2011, Qiu. Metaphysis # Yeah dot net /// how do I obtain the corresponding recursive relationship? After reading the deduction process of the Catalan number, we got some inspiration. First, a valid expression can be obtained only when the number of parentheses is a // even number. When n is an odd number, a correct expression in depth cannot be obtained, if the depth exceeds the maximum depth of the valid expression obtained by N // parentheses, the result is 0. All representations with a depth of 1 have only one type. False // T (M, d) indicates that the logarithm of parentheses is m (n = 2 * m ), if the depth does not exceed the total number of valid brace expressions of D, the following conditions are available: // T (0, d) = 1 /// otherwise, assume that E is a legal expression with D depth and M logarithm, then the leftmost bracket of expression E must be paired with a right brace R, they are combined to divide the expression into two valid parentheses, The // part between l and R, and the part on the Right of R, that is: // E = (X) Y /// assume that the left part has K pairs of parentheses, And the right part has n-k-1 pairs of parentheses, because l and R have already used a pair of parentheses, then the depth of the brackets // expression X is D-1, and the depth of the bracket expression y is D. Then the logarithm of the brackets is m, and the number of valid expressions with the depth of D is T (M, d)-T (M, d-1 ). /// T (M, d) = T (0, d-1) * t (m-1, D) + T (1, d-1) * t (m-2, D) + ...... + T (K, // d-1) * t (m-k-1, D), 0 <= k <= m-1. //// It looks like a two-dimensional version of the Catalan number. /// How many pieces of land? Obviously, the efficiency of the large number of problems is not high enough, so I improved it. The number is based on // 10000, and the number is changed to the value of Modulo 10000, use an unsigned integer to save digits. # Include <iostream> # include <vector> # include <algorithm> # include <iomanip> using namespace STD; # define maxm151 # define maxd151class INTEGER {friend ostream & operator <(ostream &, const integer &); Public: INTEGER () {}; INTEGER (unsigned int) {While (a) {digits. push_back (a % base); A/= base ;}};~ INTEGER () {}; integer operator + (integer); integer operator-(integer); integer operator * (integer); Private: void zero_justify (void ); // indicates the structure of a large number. The number of digits is in a group of four digits from the low position to the high position according to the modulo 10000, and is stored as an int type. Vector <unsigned int> digits; static unsigned int const base = 10000; static unsigned int const length = 4 ;}; // overload output symbol <. Ostream & operator <(ostream & OS, const integer & N) {OS <n. digits [n. digits. size ()-1]; for (INT I = n. digits. size ()-2; I> = 0; I --) OS <SETW (N. length) <setfill ('0') <n. digits [I]; return OS;} // remove the leading 0 produced by the large number operation. Void INTEGER: zero_justify (void) {for (INT I = digits. size ()-1; I> = 1; I --) {If (digits [I] = 0) digits. erase (digits. begin () + I); elsebreak ;}// addition operation. Integer INTEGER: Operator + (integer B) {INTEGER C; C. digits. resize (max (digits. size (), B. digits. size () + 1); int carry = 0; // carry. Int marker = 0; // Add the leading 0 for the two numbers so that the digits are the same for easy calculation. While (digits. size () <C. digits. size () digits. push_back (0); While (B. digits. size () <C. digits. size () B. digits. push_back (0); // Add one by one. While (Marker <C. digits. size () {int T = digits [Marker] + B. digits [Marker] + carry; carry = T/base; C. digits [Marker] = T % base; marker ++;} C. zero_justify (); Return C;} // subtraction. Integer INTEGER: Operator-(integer B) {INTEGER C; int borrow = 0; // borrow a digit. Int marker = 0; // counter. // Add the leading 0 to the subtrahend to facilitate computation. While (B. digits. Size () <digits. Size () B. digits. push_back (0. While (Marker <digits. size () {int v = digits [Marker]-Borrow-B. digits [Marker]; If (v <0) {v + = base; borrow = 1;} elseborrow = 0; C. digits. push_back (V % base); marker ++;} C. zero_justify (); Return C;} // multiplication. Integer INTEGER: Operator * (integer B) {INTEGER C; C. digits. resize (digits. size () + B. digits. size (); fill (C. digits. begin (), C. digits. end (), 0); For (INT I = 0; I <B. digits. size (); I ++) for (Int J = 0; j <digits. size (); j ++) {C. digits [I + J] + = digits [J] * B. digits [I]; C. digits [I + J + 1] + = C. digits [I + J]/base; C. digits [I + J] % = base;} C. zero_justify (); Return C;} integer result [maxm] [maxd]; void Init () {for (INT m = 0; m <maxm; m ++) for (int d = 0; D <maxd; D ++) result [m] [d] = INTEGER (0); For (int d = 0; D <maxd; d ++) result [0] [d] = INTEGER (1); For (int m = 1; m <maxm; m ++) for (INT d = 1; d <maxd; D ++) for (int K = 0; k <= m-1; k ++) result [m] [d] = Result [m] [d] + result [k] [d-1] * result [M-k-1] [d];} int main (int ac, char * AV []) {int N, D; Init (); While (CIN> N> D) cout <(result [n/2] [d]-result [n/2] [d-1]) <Endl; return 0 ;}