Buy the Ticket{HDU1133}

Buy the Ticket
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 6517 Accepted Submission(s): 2720

Problem Description
The "Harry Potter and the Goblet of Fire" will be on show in the next few days. As a crazy fan of Harry Potter, you will go to the cinema and have the first sight, won’t you?

Suppose the cinema only has one ticket-office and the price for per-ticket is 50 dollars. The queue for buying the tickets is consisted of m + n persons (m persons each only has the 50-dollar bill and n persons each only has the 100-dollar bill).

Now the problem for you is to calculate the number of different ways of the queue that the buying process won‘t be stopped from the first person till the last person.
Note: initially the ticket-office has no money.

The buying process will be stopped on the occasion that the ticket-office has no 50-dollar bill but the first person of the queue only has the 100-dollar bill.

Input
The input file contains several test cases. Each test case is made up of two integer numbers: m and n. It is terminated by m = n = 0. Otherwise, m, n <=100.

Output
For each test case, first print the test number (counting from 1) in one line, then output the number of different ways in another line.

Sample Input
3 0
3 1
3 3
0 0

Sample Output
Test #1:
6
Test #2:
18
Test #3:
180

f[i][j]表示有i个50j个100的方法数。当i<j时,f[i][j]=0。当i=j时,f[i][j]=f[i][j-1]。当i>j时,f[i][j]=f[i-1][j]+f[i][j-1]。

最后分别再乘上n和m的阶乘。

#include <iostream>
#include <string>
using namespace std;
#ifndef BIGNUM
#define BIGNUM
class BigNum {
#define MAXSIZEOFBIGNUM 500
#define BASE 10
#define DLEN 1
public:
    int Len;
    int d[MAXSIZEOFBIGNUM];
public:
    BigNum(void);
    BigNum(const int);
    BigNum(const char *);
    BigNum(const BigNum &);
    BigNum & operator = (const BigNum &);
    void clear(void);
    friend istream& operator>>(istream&, BigNum&);
    friend ostream& operator<<(ostream&, BigNum&);
    bool operator == (const BigNum &) const;
    bool operator > (const BigNum &) const;
    bool operator < (const BigNum &) const;
    bool operator >= (const BigNum &) const;
    bool operator <= (const BigNum &) const;
    BigNum operator + (const BigNum &) const;
    BigNum operator - (const BigNum &) const;
    BigNum operator * (const BigNum &) const;
    BigNum operator / (const BigNum &) const;
    BigNum operator % (const BigNum &) const;
    void operator ++ (void);
    void operator -- (void);
    BigNum operator + (const int &) const;
    BigNum operator - (const int &) const;
    BigNum operator * (const int &) const;
    BigNum operator / (const int &) const;
    int operator % (const int &) const;
    BigNum operator ^ (const int &) const;
    ~BigNum() {}
};
BigNum::BigNum() {
    Len = 0;
    memset(d, 0, sizeof(d));
}
BigNum::BigNum(const int ops) {
    int x = ops;
    Len = 0;
    memset(d, 0, sizeof(d));
    while(x) {
        Len++;
        d[Len] = x % BASE;
        x /= BASE;
    }
}
BigNum::BigNum(const char * ops) {
    int L = strlen(ops) - 1, b = 0;
    memset(d, 0, sizeof(d));
    while(ops[b] == ‘0‘) {
        b++;
    }
    Len = 0;
    while(L - b + 1 >= DLEN) {
        int x = 0;
        for(int i = L - DLEN + 1; i <= L; i++) {
            x = x * 10 + ops[i] - ‘0‘;
        }
        Len++;
        d[Len] = x;
        L -= DLEN;
    }
    int x = 0;
    for(int i = b; i <= L; i++) {
        x = x * 10 + ops[i] - ‘0‘;
    }
    Len++;
    d[Len] = x;
}
BigNum::BigNum(const BigNum &ops) : Len(ops.Len) {
    memset(d, 0, sizeof(d));
    for(int i = 1; i <= Len; i++) {
        d[i] = ops.d[i];
    }
}
BigNum & BigNum::operator = (const BigNum &ops) {
    memset(d, 0, sizeof(d));
    Len = ops.Len;
    for(int i = 1; i <= Len; i++) {
        d[i] = ops.d[i];
    }
    return *this;
}
void BigNum::clear(void) {
    for(int i = 1; i <= MAXSIZEOFBIGNUM - 2; i++) {
        if(d[i] < 0) {
            d[i] += BASE;
            d[i + 1]--;
        }
        if(d[i] >= BASE) {
            d[i] -= BASE;
            d[i + 1]++;
        }
    }
    for(int i = MAXSIZEOFBIGNUM - 1; i >= 1; i--)
        if(d[i] > 0) {
            Len = i;
            return;
        }
    Len = 0;
}
istream& operator>>(istream &in, BigNum &ops) {
    char str[MAXSIZEOFBIGNUM + 100];
    in >> str;
    int L = strlen(str), b = 0;
    while(str[b] == ‘0‘) {
        b++;
    }
    ops.Len = 0;
    for(int i = L - 1; i >= b; i--) {
        ops.Len++;
        ops.d[ops.Len] = str[i] - ‘0‘;
    }
    return in;
}
ostream& operator<<(ostream& out, BigNum& ops) {
    for(int i = ops.Len; i >= 1; i--) {
        out << ops.d[i];
    }
    if(ops.Len == 0) {
        out << "0";
    }
    return out;
}
bool BigNum::operator == (const BigNum &ops) const {
    if(Len != ops.Len) {
        return false;
    }
    for(int i = Len; i >= 1; i--)
        if(d[i] != ops.d[i]) {
            return false;
        }
    return true;
}
bool BigNum::operator > (const BigNum &ops) const {
    if(Len < ops.Len) {
        return false;
    } else if(Len > ops.Len) {
        return true;
    } else {
        for(int i = Len; i >= 1; i--)
            if(d[i] < ops.d[i]) {
                return false;
            } else if(d[i] > ops.d[i]) {
                return true;
            }
    }
    return false;
}
bool BigNum::operator < (const BigNum &ops) const {
    if(Len < ops.Len) {
        return true;
    } else if(Len > ops.Len) {
        return false;
    } else {
        for(int i = Len; i >= 1; i--)
            if(d[i] < ops.d[i]) {
                return true;
            } else if(d[i] > ops.d[i]) {
                return false;
            }
    }
    return false;
}
bool BigNum::operator >= (const BigNum &ops) const {
    if(Len < ops.Len) {
        return false;
    } else if(Len > ops.Len) {
        return true;
    } else {
        for(int i = Len; i >= 1; i--)
            if(d[i] < ops.d[i]) {
                return false;
            } else if(d[i] > ops.d[i]) {
                return true;
            }
    }
    return true;
}
bool BigNum::operator <= (const BigNum &ops) const {
    if(Len < ops.Len) {
        return true;
    } else if(Len > ops.Len) {
        return false;
    } else {
        for(int i = Len; i >= 1; i--)
            if(d[i] < ops.d[i]) {
                return true;
            } else if(d[i] > ops.d[i]) {
                return false;
            }
    }
    return true;
}
BigNum BigNum::operator + (const BigNum &ops) const {
    BigNum ret(*this);
    for(int i = 1; i <= ops.Len; i++) {
        ret.d[i] += ops.d[i];
    }
    ret.clear();
    return ret;
}
BigNum BigNum::operator - (const BigNum &ops) const {
    BigNum ret(*this);
    for(int i = ops.Len; i >= 1; i--) {
        ret.d[i] -= ops.d[i];
    }
    ret.clear();
    return ret;
}
BigNum BigNum::operator * (const BigNum &ops) const {
    BigNum ret, now(*this);
    for(int i = 1; i <= now.Len; i++)
        for(int j = 1; j <= ops.Len; j++) {
            ret.d[i + j - 1] += now.d[i] * ops.d[j];
        }
    for(int i = 1; i <= MAXSIZEOFBIGNUM - 2; i++)
        if(ret.d[i] >= BASE) {
            ret.d[i + 1] += ret.d[i] / BASE;
            ret.d[i] %= BASE;
        }
    for(int i = MAXSIZEOFBIGNUM - 1; i >= 1; i--)
        if(ret.d[i] > 0) {
            ret.Len = i;
            break;
        }
    return ret;
}
BigNum BigNum::operator / (const BigNum &ops) const {
    BigNum now = (*this), div, mod;
    div.Len = now.Len;
    mod.Len = 0;
    for(int j = now.Len; j >= 1; j--) {
        mod.Len++;
        for(int p = mod.Len; p >= 2; p--) {
            mod.d[p] = mod.d[p - 1];
        }
        mod.d[1] = now.d[j];
        while(mod >= ops) {
            div.d[j]++;
            mod = mod - ops;
        }
        if(mod.Len == 1 && mod.d[1] == 0) {
            mod.Len--;
        }
    }
    div.clear();
    mod.clear();
    return div;
}
BigNum BigNum::operator % (const BigNum &ops) const {
    BigNum now = (*this), div, mod;
    div.Len = now.Len;
    mod.Len = 0;
    for(int j = now.Len; j >= 1; j--) {
        mod.Len++;
        for(int p = mod.Len; p >= 2; p--) {
            mod.d[p] = mod.d[p - 1];
        }
        mod.d[1] = now.d[j];
        while(mod >= ops) {
            div.d[j]++;
            mod = mod - ops;
        }
        if(mod.Len == 1 && mod.d[1] == 0) {
            mod.Len--;
        }
    }
    div.clear();
    mod.clear();
    return mod;
}
void BigNum::operator ++ (void) {
    d[1]++;
    for(int i = 1; i <= MAXSIZEOFBIGNUM - 2; i++)
        if(d[i] >= BASE) {
            d[i] -= BASE;
            d[i + 1]++;
        } else {
            break;
        }
    if(d[Len + 1] > 0) {
        Len++;
    }
}
void BigNum::operator -- (void) {
    d[1]--;
    for(int i = 1; i <= MAXSIZEOFBIGNUM - 2; i++)
        if(d[i] < 0) {
            d[i] += BASE;
            d[i + 1]--;
        } else {
            break;
        }
    if(d[Len] == 0) {
        Len--;
    }
}
BigNum BigNum::operator + (const int & ops) const {
    BigNum ret = (*this);
    ret.d[1] += ops;
    ret.clear();
    return ret;
}
BigNum BigNum::operator - (const int & ops) const {
    BigNum ret = (*this);
    ret.d[1] -= ops;
    ret.clear();
    return ret;
}
BigNum BigNum::operator * (const int & ops) const {
    BigNum ret(*this);
    for(int i = 1; i <= ret.Len; i++) {
        ret.d[i] *= ops;
    }
    for(int i = 1; i <= MAXSIZEOFBIGNUM - 2; i++)
        if(ret.d[i] >= BASE) {
            ret.d[i + 1] += ret.d[i] / BASE;
            ret.d[i] %= BASE;
        }
    for(int i = MAXSIZEOFBIGNUM - 1; i >= 1; i--)
        if(ret.d[i] > 0) {
            ret.Len = i;
            return ret;
        }
    ret.Len = 0;
    return ret;
}
BigNum BigNum::operator / (const int & ops) const {
    BigNum ret;
    int down = 0;
    for(int i = Len; i >= 1; i--) {
        ret.d[i] = (d[i] + down * BASE) / ops;
        down = d[i] + down * BASE - ret.d[i] * ops;
    }
    ret.Len = Len;
    while(ret.d[ret.Len] == 0 && ret.Len > 1) {
        ret.Len--;
    }
    return ret;
}
int BigNum::operator % (const int &ops) const {
    int mod = 0;
    for(int i = Len; i >= 1; i--) {
        mod = ((mod * BASE) % ops + d[i]) % ops;
    }
    return mod;
}
BigNum BigNum::operator ^ (const int &ops) const {
    BigNum t, ret(1);
    if(ops == 0) {
        return ret;
    }
    if(ops == 1) {
        return *this;
    }
    int m = ops, i;
    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;
}
#endif
BigNum f[105][105];
int main() {
    f[0][0] = 1;
    for(int i = 1; i <= 100; i++) {
        for(int j = 0; j <= i; j++) {
            if(j == 0) {
                f[i][j] = 1;
                continue;
            }
            if(i == j) {
                f[i][j] = f[i][j - 1];
            } else {
                f[i][j] = f[i][j - 1] + f[i - 1][j];
            }
        }
    }
    int n, m,t=0;
    BigNum x;
    while(scanf("%d%d", &n, &m) != EOF) {
        t++;
        if(n + m == 0) {
            break;
        }
        x = f[n][m];
        for(int i = 1; i <= n; i++) {
            x = x * i;
        }
        for(int i = 1; i <= m; i++) {
            x = x * i;
        }
        cout << "Test #" << t << ":" << endl;
        cout << x << endl;;
    }
    return 0;
}

时间: 2024-07-30 21:16:12

Buy the Ticket{HDU1133}的相关文章

Buy the Ticket DP +大数

Buy the Ticket 题目抽象:有m个手持50元的人,n个手持100元的人,售票处没有准备钱.问有多少种不同的方案使得购票不中断.每个人是不同的个体. 分析:简单DP题.画个格子,那么选取的点不越过对角线y = x.  dp[i][j]表示i个100元的人,j个手持50元的人的方案数.     i<=j dp[i][j] = dp[i-1][j]+dp[i][j-1];  i>j  dp[i][j] = 0;  如果对某些点有限制,那么在递推是加条件判断. ans = dp[n][m]

hdu Buy the Ticket

1 import java.math.BigInteger; 2 import java.util.*; 3 public class Main { 4 public static void main(String []args) 5 { 6 Scanner cin=new Scanner(System.in); 7 int n,m,i; 8 int t1=0; 9 while(cin.hasNextBigInteger()) 10 { 11 t1++; 12 m=cin.nextInt();

Buy the Ticket(卡特兰数+递推高精度)

Buy the Ticket Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1886 Accepted Submission(s): 832   Problem Description The \\\\\\\"Harry Potter and the Goblet of Fire\\\\\\\" will be on show i

HDU——1133 Buy the Ticket

Buy the Ticket Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7152    Accepted Submission(s): 2998 Problem Description The "Harry Potter and the Goblet of Fire" will be on show in the nex

Codeforces 938D Buy a Ticket (转化建图 + 最短路)

题目链接  Buy a Ticket 题意   给定一个无向图.对于每个$i$ $\in$ $[1, n]$, 求$min\left\{2d(i,j) + a_{j}\right\}$ 建立超级源点$n+1$, 对于每一条无向边$(x, y, z)$,$x$向$y$连一条长度为$2z$的边,反之亦然. 对于每个$a_{i}$, 从$i$到$n+1$连一条长度为$a_{i}$的边,反之亦然. 然后跑一边最短路即可. #include <bits/stdc++.h> using namespace

Codeforces 938D Buy a Ticket

Buy a Ticket 题意要求:求出每个城市看演出的最小费用, 注意的一点就是车票要来回的. 题解:dijkstra 生成优先队列的时候直接将在本地城市看演出的费用放入队列里, 然后直接跑就好了,  dis数组存的是, 当前情况下的最小花费是多少. 代码: 1 #include<iostream> 2 #include<cstring> 3 #include<string> 4 #include<queue> 5 #include<vector&g

Codeforces 938 D. Buy a Ticket (dijkstra 求多元最短路)

题目链接:Buy a Ticket 题意: 给出n个点m条边,每个点每条边都有各自的权值,对于每个点i,求一个任意j,使得2×d[i][j] + a[j]最小. 题解: 这题其实就是要我们求任意两点的最短路,但是从点的个数上就知道这题不可以用floyd算法,其实多元最短路可以用dijkstra算.@.@!把所有的点的权值和点放到结构体里面,放入优先队列,其实这样就能保证每次拓展到的点就是这个点的最短路(因为是优先队列,保证拓展到的点这时候的值是最小的),其实就是这个点想通就很简单. 1 #inc

D. Buy a Ticket

D. Buy a Ticket Musicians of a popular band "Flayer" have announced that they are going to "make their exit" with a world tour. Of course, they will visit Berland as well. There are n cities in Berland. People can travel between cities

Codeforces 938 D. Buy a Ticket

D. Buy a Ticket time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Musicians of a popular band "Flayer" have announced that they are going to "make their exit" with a world tou