【HDU 1133】 Buy the Ticket (卡特兰数)
2016-09-20 18:37
344 查看
Buy the Ticket
[align=left]Problem Description[/align]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.
[align=left]Input[/align]
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.
[align=left]Output[/align]
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.
[align=left]Sample Input[/align]
3 0
3 1
3 3
0 0
[align=left]Sample Output[/align]
Test #1:
6
Test #2:
18
Test #3:
180
【题意】
有m个人为1,n个人为-1,他们各不同,求他们排成一列且从第一个人到任意人的权值和不能为负数的方案数(n,m<=100)
【分析】
当m<n,显然一定不合法。所以我们考虑m>=n,类比n=m时的方案数推法,总方案为C(m,m+n),要减去不符合的情况。
我们扫描一个数,找到第一个不符合的位置,假设是有a个1,a+1个1,那么我们后面会填n-a-1个-1,m-a个1,我们把后面的1和-1交换,就得到了一个有m-a个-1,n-a-1个1的数,方案为C(m+1,m+n),把它减掉即可,
即ans=C(m,m+n)-C(m+1,m+n)。因为每个人不相同最后1还要乘n!*m!。
为什么要用1和-1互换呢,首先对于一个不合法串是唯一对应一个转换串的(就按照上述方法转换),
然后对于一个转换串是一定对应一个不合法串的,方法是找到其第一个不合法的地方,然后后面部分-1和1转换。
还有就是转换串一定不合法,因为它有m+1个-1,n-1个1,而m>=n。这就是他比原串优越的地方,用他可以完全取代不合法串!
- -高精乘法。
代码如下:
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #include<queue> #include<cmath> using namespace std; #define Maxn 1100 struct node { int d[Maxn],ln; }; node t[3]; void mul(int x,int y) { int add=0; for(int i=1;i<=t[x].ln;i++) { t[x].d[i]*=y; t[x].d[i]+=add; add=t[x].d[i]/10; t[x].d[i]%=10; // if(i==t[x].ln&&t[x].d[i+1]!=0) t[x].ln++; } t[x].d[t[x].ln+1]=add; while(t[x].d[t[x].ln+1]!=0) { t[x].ln++; t[x].d[t[x].ln+1]=t[x].d[t[x].ln]/10; t[x].d[t[x].ln]%=10; } } void get_ans() { t[2].ln=t[0].ln; for(int i=1;i<=t[0].ln;i++) { if(t[0].d[i]<t[1].d[i]) { t[0].d[i+1]--; t[0].d[i]+=10; } t[2].d[i]=t[0].d[i]-t[1].d[i]; } while(t[2].d[t[2].ln]==0) t[2].ln--; if(t[2].ln==0) t[2].ln++; } int main() { int kase=0; while(1) { int m,n; scanf("%d%d",&m,&n); if(m==0&&n==0) break; printf("Test #%d:\n",++kase); if(m<n) {printf("0\n");continue;} memset(t[0].d,0,sizeof(t[0].d)); memset(t[1].d,0,sizeof(t[1].d)); t[0].d[1]=1; t[0].ln=1; for(int i=1;i<=m+n;i++) { mul(0,i); // for(int i=t[0].ln;i>=1;i--) printf("%d",t[0].d[i]);printf("\n"); } t[1].d[1]=1; t[1].ln=1; for(int i=1;i<=m;i++) { mul(1,i); } for(int i=m+2;i<=m+n;i++) { mul(1,i); } mul(1,n); get_ans(); for(int i=t[2].ln;i>=1;i--) printf("%d",t[2].d[i]); printf("\n"); } return 0; }
[HDU 1133]
2016-09-20 18:41:32
相关文章推荐
- iOS 10、Xcode 8 遇到部分问题解决记录
- sujection重构
- x264 亮度信号8x8帧内预测模式
- Android--Dialog
- sqlite中的锁及概念误区
- matlab 线性规划函数-linprog
- subjection重构
- How JavaScript Timers Work
- 方法的重载,作用域,包装类,拆箱,装箱
- mongodb安装与使用
- 快速幂计算(整数快速幂/矩阵快速幂)
- 【风马一族_C】c语言版,在2到n中寻找出所有的素数
- .net 给前台元素设置样式
- 实践:zookeeper如何在客户端上动态的监听服务器的上线和离线的
- 数字图像处理中的基本图像类型
- NFC 基础知识(NFC Basics) 根据官网个人翻译
- 关于rman中set newname的探讨
- 最大子序列和问题
- 在win7系统中安装SQL2005出现29506错误码的解决方案
- 怎么写cookie