当前位置:   article > 正文

卡特兰数 (Catalan)_卡特兰数公式

卡特兰数公式

1.卡特兰数计算公式:

公式一:时间复杂度 O( n^2 )

递推式:h(0) = h(1) = 1                        (n >= 2)

               h(n) = h(0) * h (n -1) + h(1) * h(n - 2) +.....+ h(n - 1) * h(0)         

公式二:时间复杂度 O( n )

             (大数据时h(n)很大,取模时难保证不出现 h(n) % mod = 0)

               h(n) = h(n - 1) * (4 * n - 2) / (n + 1)  

公式三:时间复杂度 O( n )

组合数公式一:     h(n) = C(2n, n) / (n + 1)                (n = 0 , 1, 2.....)        //无法取模

公式四:时间复杂度 O( n )

组合数公式二:      h(n) = C(2n, n) - C(2n, n - 1)             (n = 0, 1, 2.....)        // 可以取模

公式四可以变成公式三:

 2.例题

1.球迷购票问题(球迷购票问题 - 洛谷)

题目背景

盛况空前的足球赛即将举行。球赛门票售票处排起了球迷购票长龙。

按售票处规定,每位购票者限购一张门票,且每张票售价为50元。在排成长龙的球迷中有N个人手持面值50元的钱币,另有N个人手持面值100元的钱币。假设售票处在开始售票时没有零钱。试问这2N个球迷有多少种排队方式可使售票处不致出现找不出钱的尴尬局面。

题目描述

例如当n=2是,用A表示手持50元面值的球迷,用B表示手持100元钱的球迷。则最多可以得到以下两组不同的排队方式,使售票员不至于找不出钱。

第一种:A A B B

第二种:A B A B

[编程任务]

对于给定的n (0≤n≤20),计算2N个球迷有多少种排队方式,可以使售票处不至于找不出钱。

输入格式

一个整数,代表N的值

输出格式

一个整数,表示方案数

输入输出样例

输入 

2

输出 

2

说明/提示

必开QWORD

测试:N=15

回溯:1秒(超时)

模拟栈:大于10分钟

递归算法:1秒(超时)

动态规划:0 MS

组合算法:16 MS

AC代码:

  1. #include <iostream>
  2. #include <algorithm>
  3. using namespace std;
  4. const int N = 30;
  5. typedef unsigned long long ull;
  6. ull f[N];
  7. int main()
  8. {
  9. int n;
  10. cin >> n;
  11. f[0] = f[1] = 1;
  12. for(int i = 2; i <= n; i++ )
  13. f[i] = f[i-1] * (4 * i - 2) / (i + 1); //公式二
  14. cout << f[n] << endl;
  15. return 0;
  16. }

2.栈([NOIP2003 普及组] 栈 - 洛谷

AC代码:

  1. //法1
  2. #include <iostream>
  3. #include <algorithm>
  4. using namespace std;
  5. long long f[40];
  6. int main()
  7. {
  8. int n;
  9. cin >> n;
  10. f[0] = f[1] = 1;
  11. for(int i = 2; i <= n; i++ )
  12. f[i] = f[i - 1] * (4 * i - 2) / (i + 1); //公式二
  13. cout << f[n] << endl;
  14. return 0;
  15. }
  16. #if 0
  17. //法2
  18. #include <iostream>
  19. #include <algorithm>
  20. using namespace std;
  21. long long f[40];
  22. int main()
  23. {
  24. int n;
  25. cin >> n;
  26. f[0] = f[1] = 1;
  27. for(int i = 2; i <= n; i++ )
  28. {
  29. for(int j = 0; j < i; j++ )
  30. f[i] += f[j] * f[i - j - 1]; //递推式
  31. }
  32. cout << f[n] << endl;
  33. return 0;
  34. }
  35. #endif

3.火车进出栈问题(130. 火车进出栈问题 - AcWing题库

一列火车 n 节车厢,依次编号为 1,2,3,…,n。

每节车厢有两种运动方式,进栈与出栈,问 n节车厢出栈的可能排列方式有多少种。

输入格式

输入一个整数 n,代表火车的车厢数。

输出格式

输出一个整数 s 表示 n 节车厢出栈的可能排列方式数量。

数据范围

1 ≤ n ≤ 60000

输入样例:
3
输出样例:
5

题解:由于n最大值为6 * 1e4,数据范围过大,使用python解决.

AC代码:

  1. import math #调用阶乘函数math.factorial()
  2. a = int(input()) #输入转换为整型
  3. print(math.factorial(2 * a) // math.factorial(a) // math.factorial(a) // (a+1)) #公式三

4.火车进栈(129. 火车进栈 - AcWing题库

这里有 n 列火车将要进站再出站,但是,每列火车只有 1 节,那就是车头。

这 n列火车按 1 到 n 的顺序从东方左转进站,这个车站是南北方向的,它虽然无限长,只可惜是一个死胡同,而且站台只有一条股道,火车只能倒着从西方出去,而且每列火车必须进站,先进后出。

也就是说这个火车站其实就相当于一个栈,每次可以让右侧头火车进栈,或者让栈顶火车出站。

车站示意如图:

  1. 出站<—— <——进站
  2. |车|
  3. |站|
  4. |__|

现在请你按《字典序》输出前 20 种可能的出栈方案。

输入格式

输入一个整数 n,代表火车数量。

输出格式

按照《字典序》输出前 20 种答案,每行一种,不要空格。

数据范围

1≤n≤20

输入样例:
3
输出样例:
  1. 123
  2. 132
  3. 213
  4. 231
  5. 321

AC代码:

  1. #include <iostream>
  2. #include <algorithm>
  3. #include <stack>
  4. #include <vector>
  5. using namespace std;
  6. vector<int> v; //出栈序列
  7. stack<int> s; //栈
  8. int ans = 20, sum = 1; //ans方案数
  9. int n;
  10. void dfs()
  11. {
  12. if (!ans) //20种方案
  13. return ;
  14. if (v.size() == n)
  15. {
  16. ans--;
  17. for( auto x : v) //输出v中元素
  18. cout << x;
  19. cout << endl;
  20. return ;
  21. }
  22. if (!s.empty()) //出栈
  23. {
  24. v.push_back(s.top());
  25. s.pop();
  26. dfs();
  27. s.push(v.back()); //状态还原
  28. v.pop_back();
  29. }
  30. if(sum <= n) //进栈
  31. {
  32. s.push(sum);
  33. sum ++;
  34. dfs();
  35. sum --; //状态还原
  36. s.pop();
  37. }
  38. }
  39. int main()
  40. {
  41. cin >> n;
  42. dfs();
  43. return 0;
  44. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/76151
推荐阅读
相关标签
  

闽ICP备14008679号