hdu 1133 Buy the Ticket(卡特兰数)

来源:互联网 发布:淘宝上ios充值的原理 编辑:程序博客网 时间:2024/06/05 12:37

Buy the Ticket

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=1133

解题思路:

首先假设人无区别

令f(m,n)表示有m个人手持¥50的钞票,n个人手持¥100的钞票时共有的方案总数。则可以分以下情况讨论这个问题:

(1)当n=0时

     N=0意味着排队购票的所有人手中拿的都是 ¥50的钞票,那么这m个人排队方案总数为1。

(2)当m<n时

    显然,f(m,n)=0

(3)其他情况:
    考虑(m+n)个人排队购票的情景,第(m+n)人站在第(m+n-1)个人的后面,则第(m+n )个人的排队方式可以由下列两种

情况获得:

a.第(m+n )个人手持¥100的钞票,则在他之前的(m+(n-1))个人中有m个人手持¥50的钞票,有(n-1)个人手持¥100的钞

票,此种情况共有f(m,n-1);

b.第(m+n )个人手持¥50的钞票,则在他之前的((m-1)+n)个人中有m-1个人手持¥50的钞票,有n个人手持¥100的钞票,此

种情况共有f(m-1,n);

递推公式—— 

根据加法原理得到:

f(m,n)=f(m-1,n)+f(m,n-1)

于是得到f(m,n)的计算公式


计算示意图:

                                

所以:对于一般情况(m>=n>0)
可以推出下面直接的公式: 
f(m,n)= C(m+n,n)-C(m+n,m+1)

AC代码:

import java.math.BigInteger;import java.util.Scanner;public class Main {    public static void main(String[] args) {        Scanner sca = new Scanner(System.in);        int t = 1;        while(sca.hasNext()){            int m = sca.nextInt();            int n = sca.nextInt();            if(m+n == 0)                break;            BigInteger sum;            if(m < n)                sum = BigInteger.ZERO;            else{                sum = BigInteger.ONE;                for(int i = 1; i <= m+n; i++)                    sum = sum.multiply(BigInteger.valueOf(i));                sum = sum.multiply(BigInteger.valueOf(m-n+1));                sum = sum.divide(BigInteger.valueOf(m+1));            }            System.out.println("Test #"+t+":");            System.out.println(sum);            t++;        }    }}


0 0
原创粉丝点击