luogu P1044 火车进出栈问题(Catalan数)
Catalan数就是魔法
火车进出栈问题即:
一个栈(无穷大)的进栈序列为 1,2,3,4,...,n 求有多少个不同的出栈序列?
将问题进行抽象, 假设'+'代表进栈, 则有'-'代表出栈
那么如果进栈序列为123, 则:
+ + + - - - 将1, 2, 3压入栈后再将3, 2, 1弹出 得到出栈序列为321
同样, + - + - + - 得到出栈序列为123
上面所述的均为合法进出栈的序列 可发现规律: 序列中 + 的个数等于 - 的个数
但是如 + - - + + - 这样的序列, 在栈为空时仍进行弹出操作的, 为非法序列
进一步将 + - 序列抽象到平面直角坐标系中, + 代表向右走一格, -代表向上走一格, 可知y = x直线下方的序列均为合法序列, 如下图所示:
到这里, 火车进出栈问题就已经抽象为非降路径(只能向上走或向右走的路径)的问题
对于路径计数问题:
1)从(0,0)到(n,n)的非降路径等于n个x和n个y的排列数 即路径数为C(2n, n);
2)如果不是合法序列, 则会经过上图中的红线, 不合法序列一定会经过点(n -1, n), 从(0, 0)到(n -1, n)有C(2n, 2n-1)种不合法的路径;
3)综合1), 2) 并依据组合数性质化简
推导出公式:
我们可以得到出栈序列的总数为C(2n, n) / (n + 1).
下面以luogu P1044 栈为例, 完整代码如下:
/*
* @Author: Hellcat
* @Date: 2020-02-27 15:54:37
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll; ll C(int n, int m) {
ll ans = ;
for(ll i = ; i <= m; i++)
ans = ans * (n - m + i) / i;
return ans;
} int main() {
int n;
scanf("%d", &n);
printf("%lld\n", C(*n, n) / (n + ));
}
题给数据量不大 选择高效的组合数计算方法即可 无需高精度算法.
同时给出完全模拟的dfs暴力搜索算法如下:
dfs时候需要注意 为保证字典序输出优先考虑出栈.
#include <bits/stdc++.h>
using namespace std; int n, cnt = ;
vector<int> state1;
stack<int> state2;
int state3 = ; int res = ; void dfs() {
if(!cnt) return;
if(state1.size() == n) {
res++;
cnt--;
for(auto x : state1) cout<<x;
puts("");
return;
}
// 按字典序输出 则出栈先
if(state2.size()) { // 出栈
state1.push_back(state2.top());
state2.pop();
dfs();
state2.push(state1.back()); // 回溯
state1.pop_back();
}
if(state3 <= n) { // 入栈
state2.push(state3);
state3++;
dfs();
state3--; // 回溯
state2.pop();
}
} int main() {
scanf("%d", &n);
dfs();
printf("%d\n", res);
}
输入
3
输出
123
132
213
231
321
5
luogu P1044 火车进出栈问题(Catalan数)的更多相关文章
- 【讲●解】火车进出栈类问题 & 卡特兰数应用
火车进出栈类问题详讲 & 卡特兰数应用 引题:火车进出栈问题 [题目大意] 给定 \(1\)~\(N\) 这\(N\)个整数和一个大小无限的栈,每个数都要进栈并出栈一次.如果进栈的顺序为 \( ...
- tyvj/joyoi 1374 火车进出栈问题(水水版)
我受不了了. Catalan数第100项,30000项,50000项,cnm 这tm哪里是在考数学,分明是在考高精度,FFT...... 有剧毒! 我只得写高精度,只能过100的那个题,两个进化版超时 ...
- CH1102 火车进出栈问题(高精/卡特兰数)
描述 一列火车n节车厢,依次编号为1,2,3,-,n.每节车厢有两种运动方式,进栈与出栈,问n节车厢出栈的可能排列方式有多少种. 输入格式 一个数,n(n<=60000) 输出格式 一个数s表示 ...
- 洛谷P1044 栈(Catalan数)
P1044 栈 题目背景 栈是计算机中经典的数据结构,简单的说,栈就是限制在一端进行插入删除操作的线性表. 栈有两种最重要的操作,即pop(从栈顶弹出一个元素)和push(将一个元素进栈). 栈的重要 ...
- 火车进出栈 java
题目描述 一列火车n节车厢,依次编号为1,2,3,…,n.每节车厢有两种运动方式,进栈与出栈,问n节车厢出栈的可能排列方式有多少种. 输入 一个数,n(n<=60000) 输出 一个数s表示n节 ...
- Catalan数与出栈顺序个数,Java编程模拟
问题描述: 队列中有从1到7(由小到大排列)的7个整数,问经过一个整数栈后,出栈的所有排列数有多少?如果整数栈的容量是4(栈最多能容纳4个整数),那么出栈的排列数又是多少? 分析:对于每一个数字i, ...
- Catalan数 && 【NOIP2003】出栈序列统计
令h(1)=1, h(0)=1,catalan数满足递归式: h(n)=h(0)*h(n-1)+h(1)*h(n-2)+...+h(n-1)h(0) (n>=2) =C(2n, n)/(n+1) ...
- Catalan数,括号序列和栈
全是入门的一些东西.基本全是从别处抄的. 栈: 支持单端插入删除的线性容器. 也就是说,仅允许在其一端加入一个新元素或删除一个元素. 允许操作的一端也叫栈顶,不允许操作的一端也叫栈底. 数个箱子相叠就 ...
- [Catalan数]1086 栈、3112 二叉树计数、3134 Circle
1086 栈 2003年NOIP全国联赛普及组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 栈是计算机中 ...
随机推荐
- html input file 设置文件类型
解决方案: 使用 input 的 accept 属性指定接受文件类型 -----------更新--------------- 之前的代码有个缺点,打开文件窗口时会自动筛选文件夹下所有符合设定类型的文 ...
- 8.5-Day1T1--Asm.Def 谈笑风生
题目大意 m个操作, 1:添加一个字符串 2:查询字符串s是否被添加过(中至多包含一个通配符“*”) 题解 trie树可以得部分分 用map映射 '*'就枚举26个英文字母来判断就可以了 #inclu ...
- ANSYS中 *VWRITE命令使用
目录 1. *VWRITE命令 2. Fortran字段描述符 1. *VWRITE命令 ANSYS输出结果到文件,采用*VWRITE命令,具体命令如下: *VWRITE,Par1,Par2,.... ...
- cas的单点登录实现
1. 前提条件 环境:jdk1.8.shiro1.4.0及以上版本.项目以 spring+shiro构建 工具:buji-pac4j-3.1.0-jar-with-dependencies.jar以 ...
- netty(三)---NioEventLoop分析
问题 : NioEventLoop 作用到底是什么?是在哪里用到的? NioEventLoop 和我们开头创建的 ServerBootstrap 和 EventLoopGroup 是什么关系 ? Ni ...
- android studio中project structure配置
android studio project structure 1.project中填jdk路径 2.module中添androidsdk路径 3.sdks中填jdk路径
- VS2017中遇到不存在从string到const char*的转换函数的解决方法
使用c_str()函数 c_str函数的返回值是const char*. c_str()函数返回一个指向正规C字符串的指针, 内容与本string串相同. 这是为了与c语言兼容,在c语言中没有stri ...
- Django 实现下载功能时中文文件名问题
先上最终解决代码(有待验证各浏览器效果): def download_file(request, file_path): file_name = os.path.basename(file_path) ...
- python应用-pycharm新建模板默认添加shebang编码作者时间等信息
1.pycharm4.5激活码 用户名: yueting3527 注册码: ===== LICENSE BEGIN ===== 93347-12042010 00001FMHemWIs"6w ...
- photoshop下载(ps)
https://pan.baidu.com/s/1bNrUod2n1VqsA7Fr9RHtsg