[Large number + dp] HDU 1133 -- buy the tickets (no more Catalan)

Source: Internet
Author: User

Question: Click to open the link

There are some people who have 100 and 50 yuan. They come to buy a ticket. One ticket is 50, and there is no change for the cinema. They can only accept 50 yuan for another 100 yuan, ask how many valid methods to find money.

Method 1:

The Catalan number in composite mathematics can be used to explain Catalan's practice:

Valid arrangement mode = All arrangement modes-illegal arrangement

Here, the calculation of the illegal arrangement is: (-) * m! * N!

However, in this question, because everyone is different, we need to multiply it by M! * N!

So the final equation is obtained:

F (n) = (-) * m! * N!
;

Then, simplify the process;

F (n) = (m + n )! * (M-N + 1)/(m + 1)

Method 2:

Unfortunately, I cannot think of this method .. Therefore, DP is widely used.

First of all, we can think that when m is less than N, 100 more than 50 will certainly not be able to change, and there is no way to talk about the number of changes, all are 0.

When no one takes 100, the sort and combination of money collection will naturally be m !.

If someone takes 100, they need to find the money. The number of methods for finding the money can be deduced using a combination formula --

DP [I] [J] = x * DP [I-1] [J] + y * DP [I] [J-1].

When selecting the person I, there are (n-I + 1) options to find money. I, j indicates that I bought a ticket for 50 yuan, and J bought a ticket for 100 yuan. In combination with the big data template just mined on the internet, it becomes a common DP problem.

# Include <iostream> # include <string> # include <iomanip> # include <algorithm> using namespace STD; # define maxn 9999 # define maxsize 10 # define dlen 4 class bignum {PRIVATE: int A [500]; // The number of digits that can be controlled for a large number int Len; // the length of a large number is public: bignum () {Len = 1; memset (A, 0, sizeof (a);} // constructor bignum (const INT ); // convert a variable of the int type to the bignum (const char *); // convert a variable of the string type to the bignum (const bignum &); // copy the constructor bignum & operator = (const bignum &); // Overload the value assignment operator. The value assignment operation between large numbers is friend istream & operator> (istream &, bignum &); // reload the input operator friend ostream & operator <(ostream &, bignum &); // reload the output operator bignum operator + (const bignum &) const; // reload the addition operator, bignum operator-(const bignum &) const; // overload subtraction operator, subtraction between two large numbers bignum operator * (const bignum &) const; // reload the multiplication operator. bignum operator/(const Int &) const; // reload the Division operator to remove an integer. bignum operator ^ (Const Int &) const; // nth power operation of large numbers int operator % (const Int &) const; // perform the modulo operation bool operator> (const bignum & T) const on an int type variable in a large number; // compare the size of a large number with that of another large number bool operator> (const Int & T) const; // compare the size of a large number with that of an int Type Variable Void print (); // output large number}; bignum: bignum (const int B) // convert an int type variable to a large number {int C, D = B; Len = 0; memset (A, 0, sizeof (a); While (D> maxn) {c = D-(D/(maxn + 1) * (maxn + 1 ); D = D/(maxn + 1); A [Len ++] = C;} A [L En ++] = D;} bignum: bignum (const char * s) // convert a variable of the string type to a large number {int T, K, index, l, i; memset (A, 0, sizeof (a); L = strlen (s); Len = L/dlen; If (L % dlen) Len ++; index = 0; for (I = L-1; I> = 0; I-= dlen) {T = 0; k = I-dlen + 1; if (k <0) k = 0; For (Int J = K; j <= I; j ++) t = T * 10 + s [J]-'0 '; A [index ++] = T ;}} bignum: bignum (const bignum & T): Len (T. len) // copy the constructor {int I; memset (A, 0, sizeof (a); for (I = 0; I <Len; I ++) A [I] = T. A [I];} bignum & bignum: Opera Tor = (const bignum & N) // overload the value assignment operator. assign values between large numbers {int I; Len = n. len; memset (A, 0, sizeof (a); for (I = 0; I <Len; I ++) A [I] = n. A [I]; return * This;} istream & operator> (istream & in, bignum & B) // reload the input operator {char ch [maxsize * 4]; int I =-1; in> CH; int L = strlen (CH); int COUNT = 0, sum = 0; for (I = L-1; I> = 0 ;) {sum = 0; int T = 1; for (Int J = 0; j <4 & I> = 0; j ++, I --, T * = 10) {sum + = (CH [I]-'0') * t;} B. A [count] = sum; count ++;} B. len = count ++; R Eturn in;} ostream & operator <(ostream & out, bignum & B) // overload the output operator {int I; cout <B. A [B. len-1]; for (I = B. len-2; I> = 0; I --) {cout. width (dlen); cout. fill ('0'); cout <B. A [I];} return out;} bignum: Operator + (const bignum & T) const // The addition operation between two large numbers {bignum T (* This ); int I, big; // The number of digits big = T. len> Len? T. len: Len; for (I = 0; I <big; I ++) {T. A [I] + = T. A [I]; If (T. A [I]> maxn) {T. A [I + 1] ++; T. A [I]-= maxn + 1 ;}} if (T. A [Big]! = 0) T. len = big + 1; elset. len = big; return t;} bignum: Operator-(const bignum & T) const // subtraction between two large numbers {int I, j, big; bool flag; bignum T1, T2; If (* This> T) {T1 = * This; t2 = T; flag = 0;} else {T1 = T; t2 = * this; flag = 1 ;}big = t1.len; for (I = 0; I <big; I ++) {If (t1.a [I] <t2.a [I]) {J = I + 1; while (t1.a [J] = 0) J ++; t1.a [j --] --; while (j> I) t1.a [j --] + = maxn; t1.a [I] + = maxn + 1-t2.a [I];} elset1.a [I]-= t2.a [I];} t1.len = big; while (t1.a [Len-1] = 0 & t1.len> 1) {t1.len --; big --;} If (FLAG) t1.a [Big-1] = 0-t1.a [Big-1]; return T1;} bignum: Operator * (const bignum & T) const // multiplication between two large numbers {bignum ret; int I, j, up; int temp, temp1; for (I = 0; I <Len; I ++) {up = 0; For (j = 0; j <t. len; j ++) {temp = A [I] * t. A [J] + ret. A [I + J] + up; If (temp> maxn) {temp1 = temp-temp/(maxn + 1) * (maxn + 1); up = Temp/(maxn + 1); ret. A [I + J] = temp1;} else {up = 0; ret. A [I + J] = temp ;}} if (up! = 0) ret. A [I + J] = up;} ret. len = I + J; while (Ret. A [ret. len-1] = 0 & ret. len> 1) ret. len --; return ret;} bignum: Operator/(const Int & B) const // perform the division operation on an integer {bignum ret; int I, down = 0; for (I = len-1; I> = 0; I --) {ret. A [I] = (a [I] + down * (maxn + 1)/B; down = A [I] + down * (maxn + 1)-ret. A [I] * B;} ret. len = Len; while (Ret. A [ret. len-1] = 0 & ret. len> 1) ret. len --; Return ret;} int bignum: Operator % (const Int & B) const // a large number of Modulo operations on an int type variable {int I, D = 0; for (I = len-1; I> = 0; I --) {d = (D * (maxn + 1) % B + A [I]) % B ;} return D;} bignum: operator ^ (const Int & N) const // Npower operation of large numbers {bignum T, RET (1); int I; if (n <0) Exit (-1); If (n = 0) return 1; if (n = 1) return * This; int M = N; while (M> 1) {T = * this; for (I = 1; I <1 <= m; I <= 1) {T = T * t ;} m-= I; ret = RET * t; If (M = 1) ret = RET * (* This);} return RET;} bool bignum: Operator> (const bignum & T) const // compare the size of a large number with that of another one {int ln; If (LEN> T. len) return true; else if (LEN = T. len) {Ln = len-1; while (A [Ln] = T. A [Ln] & ln> = 0) ln --; If (LN> = 0 & A [Ln]> T. A [Ln]) return true; elsereturn false;} bool bignum: Operator> (const Int & T) const // compare the size of a large number and an int type variable {bignum B (t); return * This> B;} void bignum: Print () // output large number {int I; cout <A [Len-1]; for (I = len-2; I> = 0; I --) {cout. width (dlen); cout. fill ('0'); cout <A [I];} cout <Endl;} bignum DP [103] [103]; int main () {int A = 1, B = 1; int casenum = 1; while (CIN> A> B & (! = 0 | B! = 0) {int tmpa = A; int tmpb = B; cout <"test #" <casenum <":" <Endl; if (a <B) {cout <0 <Endl; casenum ++; continue;} else {for (INT I = 0; I <= 102; I ++) {for (Int J = 0; j <= 102; j ++) {DP [I] [J] = 0 ;}} DP [0] [0] = 1; for (INT I = 1; I <= A; I ++) {DP [0] [I] = DP [0] [I-1] * tmpa; // calculate the factorial, you can also dynamically plan tmpa --;} For (INT I = 1; I <= B; I ++) {for (Int J = I; j <=; j ++) {DP [I] [J] = (DP [I-1] [J] * (B + 1-I )) + (DP [I] [J-1] * (a + 1-j);} DP [B] [a]. print () ;}casenum ++ ;}}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.