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 栈是计算机中 ...
随机推荐
- 连接查询:inner join,left join,right join
感谢原创:https://blog.csdn.net/plg17/article/details/78758593 准备工作: 1)新建两张表a_table和b_table: create table ...
- STA之RC网
STA的主要工作是计算电路网络的延时,如今的电路网络还是由CMOS cell和net组成的,所以STA所要计算的延时仍是电容的充放电时间.等量子计算机普及的时候,如今的这一套理论都将随着科技的进步被丢 ...
- X-Frame-Options报错处理
项目中用到iframe嵌入网页,因为是前后端分离的,所以前端会报错Refused to display ‘网址' in a frame because it set 'X-Frame-Options' ...
- JAVA(4)之关于项目部署在tomcat
关于项目部署的报错问题一直是找不到项目 在重装几次tomcat9和tomcat7后找到了原因,关键原因是访问路径不正确,项目名拼写错误. 排除问题的思路如下(控制变量法) 工作方法和思路 列出步骤,从 ...
- 循环select和取赋值
bootstrap: <!--列表容器--> <div class="panel-body" style="position:relative;&quo ...
- [代码记录] C语言链表
#开始 · 简单的创建链表 #代码 #include<conio.h> #include<stdio.h> #include<stdlib.h> struct St ...
- IIS-URL重写参数
参考:https://www.cnblogs.com/gggzly/p/5960335.html URL 重写规则由以下部分组成: 模式 - 可以理解为规则,分通配符和正则匹配 条件 - 可以 ...
- ajax请求ashx跨域问题解决办法
ajax请求ashx跨域问题解决办法 https://blog.csdn.net/windowsliusheng/article/details/51583566 翻译windowsliusheng ...
- idea 快捷使用(二)回退断点的使用
在调试的时候,想要重新走一下流程而不用再次发起一个请求? 1.所谓的断点回退,其实就是回退到上一个方法调用的开始处,在IDEA里测试无法一行一行地回退或回到到上一个断点处,而是回到上一个方法.回退的方 ...
- sqlserver数据库中char、varchar、text与nchar、nvarchar、ntext数据类型使用详解
很多开发者进行数据库设计的时候往往并没有太多的考虑char, varchar类型,有的是根本就没注意,因为存储价格变得越来越便宜了,忘记了最开始的一些基本设计理论和原则,这点让我想到了现在的年轻人,大 ...