【HDU 1133】 Buy the Ticket (卡特兰数)


【分析】

  

  当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。这就是他比原串优越的地方,用他可以完全取代不合法串!

代码如下:(还没有测,hdu挂掉了)

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 #include<queue>
 7 #include<cmath>
 8 using namespace std;
 9 #define Maxn 110
10
11 struct node
12 {
13     int d[Maxn],ln;
14 };
15 node t[3];
16
17 void mul(int x,int y)
18 {
19     int add=0;
20     for(int i=1;i<=t[x].ln;i++)
21     {
22         t[x].d[i]*=y;
23         t[x].d[i]+=add;
24         add=t[x].d[i]/10;
25         t[x].d[i]%=10;
26         // if(i==t[x].ln&&t[x].d[i+1]!=0) t[x].ln++;
27     }
28     t[x].d[t[x].ln+1]=add;
29     while(t[x].d[t[x].ln+1]!=0)
30     {
31         t[x].ln++;
32         t[x].d[t[x].ln+1]=t[x].d[t[x].ln]/10;
33         t[x].d[t[x].ln]%=10;
34     }
35 }
36
37 void get_ans()
38 {
39     t[2].ln=t[0].ln;
40     for(int i=1;i<=t[0].ln;i++)
41     {
42         if(t[0].d[i]<t[1].d[i])
43         {
44             t[0].d[i+1]--;
45             t[0].d[i]+=10;
46         }
47         t[2].d[i]=t[0].d[i]-t[1].d[i];
48     }
49     while(t[2].d[t[2].ln]==0) t[2].ln--;
50     if(t[2].ln==0) t[2].ln++;
51 }
52
53 int main()
54 {
55     int kase=0;
56     while(1)
57     {
58         int m,n;
59         scanf("%d%d",&m,&n);
60         if(m==0&&n==0) break;
61         printf("Test #%d:\n",++kase);
62         if(m<n) {printf("0\n");continue;}
63         memset(t[0].d,0,sizeof(t[0].d));
64         memset(t[1].d,0,sizeof(t[1].d));
65         t[0].d[1]=1; t[0].ln=1;
66         for(int i=1;i<=m+n;i++)
67         {
68             mul(0,i);
69         }
70         t[1].d[1]=1; t[1].ln=1;
71         for(int i=1;i<=m;i++)
72         {
73             mul(1,i);
74         }
75         for(int i=m+2;i<=m+n;i++)
76         {
77             mul(1,i);
78         }
79         mul(1,n);
80         get_ans();
81         for(int i=t[2].ln;i>=1;i--) printf("%d",t[2].d[i]);
82         printf("\n");
83     }
84     return 0;
85 }

[HDU 1133]

2016-09-07 22:06:16

时间: 2024-08-04 20:05:30

【HDU 1133】 Buy the Ticket (卡特兰数)的相关文章

HDU 1133 Buy the Ticket 卡特兰数

设50元的人为+1 100元的人为-1 满足前任意k个人的和大于等于0 卡特兰数 C(n+m, m)-C(n+m, m+1)*n!*m! import java.math.*; import java.util.*; public class Main { /** * @param args */ public static void main(String[] args) { Scanner sc = new Scanner(System.in); int cas = 1; while(tru

HDOJ/HDU 1133 Buy the Ticket(数论~卡特兰数~大数~)

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

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

HDU 1133 Buy the Ticket

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

hdu 5177 (1e18范围的卡特兰数)

hdu 5177 (1e18范围的卡特兰数) 题意: 求第n个卡特兰数,模3814697265625 (5^18) 限制: 有20组数据,1 <= n <= 1e18 思路: 1. 卡特兰数的表达式: ans = 1/(n+1) * C(2*n,n) -> ans = 1/(n+1) * (2n)! / n! / n!    ---1式 2. 因为要模5^18,求逆元要求互质,所以先把"1式"中的因子5全部去掉 3. 然后看不含因子5的阶乘,f(n!) 4. 设g(x

hdoj 1133 Buy the Ticket 【卡特兰】

题意:有m个人(拿50元)和n个人(拿100元)去买票,售票厅刚开始没有,问最后所有人都能够买到的方式的种类数. 这道题也是经典的卡特兰数类型题. 我们可以将他们看做是火车进出站,但是由于人是不同的,所以最后还要乘上m!*n! 最后的数学表达是就是(C(m+n,n)-C(m+n, m+1))*m!*n!=> 结果为 (m!*n!)*(m+1-n)/(m+1) 注:m<n时 直接输出0 代码: import java.util.Scanner; import java.math.*; publi

HDU 1023 Train Problem II (卡特兰数,经典)

题意:给出一个数字n,假设火车从1~n的顺序分别进站,求有多少种出站序列. 思路:卡特兰数的经典例子.n<101,用递推式解决.需要使用到大数.n=100时大概有200位以下. 1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N=101; 4 vector<string> vect; 5 void _mult(string num1, string num2, string &result )

hdu 3723 Card Game(JAVA,卡特兰数)

很容易想到的卡特兰数,不过复杂度高精度还是挺恶心的. 于是用JAVA秒杀了. import java.math.BigInteger; import java.util.Scanner; public class Main { static BigInteger[] f=new BigInteger[5005]; static BigInteger[] c=new BigInteger[10005]; static BigInteger MOD; static void init(){ f[0]

HDU Train Problem II (卡特兰数+大数)

Problem Description As we all know the Train Problem I, the boss of the Ignatius Train Station want to know if all the trains come in strict-increasing order, how many orders that all the trains can get out of the railway.   Input The input contains