Hdu 1133 Buy the ticket <卡特兰数+大数处理>

题意:

有m个人拿50 n个人拿100 前台没零钱..问多少种合法的排队方法

思路:

网上摘录:

假设m=4,n=3,的一个序列是:0110100显然,它不合法

然后我们把他稍微变化一下:把第一个不合法的“1”后面的所有数0位为1, 1位为0;这样我们得到了另一个序列:0111011,说明每个不合法的都有一个这样的序列跟他一一对应

所以计算公式就是:合法的排列方式=所有排列方式-非法排列方式

这里非法排列方式的计算 就是:($$C_{m+n}^{m}$$$$C_{m+n}^{m+1}$$ )*M!*N!

然而在这题,因为每个人都是不同的,所以还要乘以 M!*N!

所以得出最终方程:

F(N)=($$C_{m+n}^{m}$$-$$C_{m+n}^{m+1}$$)*M!*N!  ;

然后再化简一下;

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

 

Tips:

注意有n>m的情况..

还有各种大数的处理..

Code:

View Code
 1 #include <stdio.h>
 2 #include <cstring>
 3 using namespace std;
 4 #define MAX 100     ///大数的位数
 5 #define Base 10000
 6 
 7 void multiply(int *a, int b) ///大数a*小数b
 8 {
 9     int i, tmp = 0;
10     for(i = MAX - 1; i >= 0; --i){
11         tmp += b*a[i];
12         a[i] = tmp%Base;
13         tmp /= Base;
14     }
15 }
16 
17 void divide(int *a, int b)///大数a除小数b
18 {
19     int i, div = 0;
20     for(i = 0; i < MAX; ++i){
21         div = div*Base + a[i];
22         a[i] = div/b;
23         div %= b;
24     }
25 }
26 
27 int f[210][MAX];
28 void setFact()///大数阶乘<200>
29 {
30     f[0][MAX-1] = f[1][MAX-1] = 1;
31     for(int i = 2; i <= 200; ++i){
32         memcpy(f[i], f[i-1], MAX*sizeof(int));
33         multiply(f[i], i);
34     }
35 }
36 
37 void outPut(int *ans)
38 {
39     int i = 0;
40     while(i < MAX && ans[i] == 0)
41     i++;
42     printf("%d", ans[i++]);
43     while(i < MAX)
44     printf("%04d", ans[i++]);
45     puts("");
46 }
47 
48 
49 int main()
50 {
51     int i, j, k;
52     int m, n;
53     int T = 1;
54     int ans[MAX];
55     setFact();
56     while(scanf("%d %d", &m, &n), m+n)
57     {
58         printf("%Test #%d:\n", T++);
59         if(n > m){
60             printf("0\n");
61             continue;
62         }
63         memcpy(ans, f[m+n], MAX*sizeof(int));   /// ( m + n )!
64         multiply(ans, m-n+1);              ///(m+n)! * (m-n+1)
65         divide(ans, m+1);                  ///(m+n)! * (m-n+1)/(m+1)
66         outPut(ans);
67     }
68     return 0;
69 }

 

 

 

posted @ 2012-08-06 17:31  Griselda.  阅读(557)  评论(0编辑  收藏  举报