Catalan数,括号序列和栈
全是入门的一些东西.基本全是从别处抄的.
栈: 支持单端插入删除的线性容器. 也就是说,仅允许在其一端加入一个新元素或删除一个元素. 允许操作的一端也叫栈顶,不允许操作的一端也叫栈底.
数个箱子相叠就可以认为是一个栈,只能在最顶端加入一个新箱子或拿走一个箱子.
栈中的元素遵循后进先出(last in first out,LILO)的规律.即:更早出栈的元素,应为更早入栈者.
这是一个演示:
奇数行为栈中元素(右端可以进行插入删除),元素以逗号隔开, EMPTY表示栈为空
偶数行为进行的操作
EMPTY
插入10
10
插入20
10,20
插入51
10,20,51
插入10
10,20,51,10
删除一个元素
10,20,51
删除一个元素
10,20
插入30
10,20,30
删除一个元素
10,20
删除一个元素
10
删除一个元素
EMPTY
栈混洗问题
给出三个栈S1,S2,S3,一开始S1中含有1到n的n个数字且从栈顶到栈底数字依次为1,2,3,....n-1,n.
只有两种允许的操作:
A S1非空时从S1取出一个元素放入S2,
B S2非空时可以从S2取出一个元素放入S3.
最后S3中自底向上形成的序列称作一个栈混洗.
例如,如果S1中一开始有1,2,3,4四个元素,那么先进行4次A操作再进行4次B操作,将得到序列4,3,2,1.如果A操作和B操作交替进行,将得到序列1,2,3,4.
显然,栈混洗的结果并不唯一.
一个长为n的序列的栈混洗可以表示成n次A操作和n次B操作组成的一个操作序列. 而n次A操作和n次B操作组成的一个操作序列也可以表示唯一的一个栈混洗序列.
不同的操作序列必然得到不同的栈混洗,不同的栈混洗也必然对应不同的操作序列.
并不是所有含有n个A,n个B的序列都是合理的操作序列.例如BBBBAAAA,将导致我们尝试拿出空栈S2中的元素.
一个序列合理的条件是:对于任意m(1<=m<=2n),该序列的前m个操作中,B操作的数目不超过A操作的数目.只要满足这个条件就能保证任意时刻不会拿出空栈中的元素.
如何判断一个栈混洗序列是否是可能出现的栈混洗序列
例如,对于序列1,2,3,通过栈混洗可以得到[1,2,3],[3,2,1],[1,3,2],[2,1,3],[2,3,1],但是无法得到[3,1,2].如果使3最先出栈,那么就必须先令1,2入栈,从而2会在1之前出栈,只能得到[3,2,1]
任意给出一个n和一个排列,如何判断这个排列能否通过栈混洗得到?例如,n=5,序列为5,4,1,3,2,是否可能?
直接的思路是,直接根据我们要得到的序列,尝试进行A操作和B操作.例如,n=5时,要使序列的第一个元素为5,就必须一直进行A操作直到5出现在S2的栈顶.之后需要4,4恰好在S2的栈顶,于是弹出4.接下来需要的1不在栈顶,因此这个序列无法通过栈混洗得到.时间复杂度显然为O(n).其正确性也是显然的.
栈混洗与括号序列
首先只考虑由一种括号组成的括号序列.
()()()(),(()())(),((()))都是能够匹配的括号序列.)(,))(,())(都是不能够匹配的括号序列.
只要将A操作与左括号"("对应,B操作与右括号")"对应,栈混洗的合法操作序列就可以和能够匹配的括号序列一一对应.
例如,AABB对应(()),ABAB对应()()
按照我们之前的理解,如果保证序列中左右括号数目相同,那么我们只需要扫描一遍序列并维护一个计数器,初始为0,遇到左括号+1,遇到右括号-1,只要这个计数器的数值始终非负,就说明任意一个前缀中左括号的数目多于右括号的数目,等价于这个序列是能够匹配的括号序列.
另一种判断括号序列是否合法的方法:初始化一个空栈S,从左向右扫描序列,遇到一个左括号将其入栈,遇到一个右括号时判断栈中是否有一个左括号,如果有,那么这个左括号与当前遇到的右括号相匹配.如果栈为空,那么这个括号序列并不合法.通过这种方式,我们除了得知括号序列是否合法,还可以得知每个右括号具体是和哪个左括号匹配,还可以处理序列中出现了多种括号且只有对应种类的括号能匹配的情况.可以自行尝试,"维护一个计数器"的方式并不能方便地扩展到多种括号的情况.
拓展:允许循环移位的合法括号序列
允许将括号序列的最左侧元素拿到最右边,问能否通过若干次这样的操作使得括号序列合法.
首先这样的序列仍然需要满足左括号和右括号数目相同. 但是除此之外还需要满足什么条件呢?
令人惊讶的是,除此之外并不需要满足什么条件.只要左括号和右括号数目相同,就可以保证能够通过若干次循环移位使得括号序列合法.
给出一个构造方式:将左括号视为1,右括号视为-1,求取该序列的前缀和.如果前缀和中的最小值为0那么序列本身就是合法的.否则我们找到前缀和的最小值的出现位置(多个数值相同时取最左侧的),将这个位置之前的一段序列移位到右端,得到的即为合法的括号序列.构造方式的正确性不难证明.
括号序列计数
有多少个不同的含有n对括号的合法括号序列?这个问题等价于通过栈混洗可以得到多少个不同序列.也等价于,有多少个含有n个0,n个1的长为2n的字符串使得任意一个前缀中1的数目不少于0的数目.
假设答案为f[n].边界条件为f[0]=1,表示没有括号/没有元素时也算有一种方案(空串也是一种合法序列).
插播两条高中数学:
分类加法计数原理:做一件事有m类方法,每类方法分别有A1,A2...Am种做法,那么做这件事共有\(A1+A2+...+Am\)种方法
分步乘法计数原理:做一件事有m个步骤,每个步骤分别有A1,A2...Am种做法,那么做这件事共有\(A1*A2*...*Am\)种方法
好了,接下来我们来将所学的用于实践.
考虑最左侧的左括号匹配的右括号在什么位置.假设这个左括号和匹配的右括号之间有2i个括号(这个数目必须是偶数),这2i个括号排列成合法括号序列的方案数为f[i].匹配的右括号右边还有2n-2i-2个括号,将它们排列为合法括号序列的方案数为f[n-i-1],这两部分可以认为是两个步骤,是独立的,那么总的方案数是f[i]*f[n-i-1].
对于不同的i,我们可以认为是做一件事的不同种类的方法.
于是\(f[1]=f[0]*f[0],f[2]=f[1]*f[0]+f[0]*f[1],f[3]=f[0]*f[2]+f[1]*f[1]+f[2]*f[0]\),这是一个O(n^2)的计算方式.
这里我们得到的f[n]也叫Catalan数(卡特兰数),它还具有很多实际意义.
紫书330~331页给出了Catalan数的另一个实际意义:多边形三角剖分数目,并通过另一个O(n^2)的递推公式,推倒了O(n)的递推公式.
另一个常用的计算公式是f[n]=C(2n,n)/(n+1)=C(2n,n) - C(2n,n-1),C(2n,n)为组合数.
catalan数的一个推广:
n个左括号,m个右括号,任意前缀中左括号不少于右括号的序列数?答案是C(n+m,m)-C(n+m,m-1).
Catalan数,括号序列和栈的更多相关文章
- 洛谷 P1241 括号序列(栈)
嗯... 题目链接:https://www.luogu.org/problem/P1241 首先这道题是栈的入门题的加强版, 不仅要你判断这个括号序列是否合法,还要你将这个序列补充完整... 一开始是 ...
- catalan 数——卡特兰数(转)
Catalan数——卡特兰数 今天阿里淘宝笔试中碰到两道组合数学题,感觉非常亲切,但是笔试中失踪推导不出来后来查了下,原来是Catalan数.悲剧啊,现在整理一下 一.Catalan数的定义令h(1) ...
- (转载)Catalan数——卡特兰数
Catalan数——卡特兰数 今天阿里淘宝笔试中碰到两道组合数学题,感觉非常亲切,但是笔试中失踪推导不出来后来查了下,原来是Catalan数.悲剧啊,现在整理一下 一.Catalan数的定义令h(1) ...
- 12个高矮不同的人,排成两排(catalan数)
问题描述: 12个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高,问排列方式有多少种? 这个笔试题,很YD,因为把某个递归关系隐藏得很深. 问题分析: 我们先把这12个 ...
- 2020牛客寒假算法基础集训营4 B:括号序列
B : 括号序列 考察点 : 栈 坑点 : 只有栈空时才是合法的 Code: #include <stack> #include <cstdio> #include <s ...
- 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数]1086 栈、3112 二叉树计数、3134 Circle
1086 栈 2003年NOIP全国联赛普及组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 栈是计算机中 ...
- codevs 1086 栈(Catalan数)
题目描述 Description 栈是计算机中经典的数据结构,简单的说,栈就是限制在一端进行插入删除操作的线性表. 栈有两种最重要的操作,即pop(从栈顶弹出一个元素)和push(将一个元素进栈). ...
- luogu P1044 火车进出栈问题(Catalan数)
Catalan数就是魔法 火车进出栈问题即: 一个栈(无穷大)的进栈序列为 1,2,3,4,...,n 求有多少个不同的出栈序列? 将问题进行抽象, 假设'+'代表进栈, 则有'-'代表出栈 那么如果 ...
随机推荐
- 20145226夏艺华 《Java程序设计》第10周学习总结
教材学习内容总结 学习目标 了解计算机网络基础 掌握Java Socket编程 网络编程 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据.程序员所作的事情就是把数据发送到指定的位置,或者 ...
- WPF使用IDataErrorInfo接口进行数据校验 - 简书
原文:WPF使用IDataErrorInfo接口进行数据校验 - 简书 class ValidationBindableBase : BindableBase, IDataErrorInfo { pu ...
- BZOJ2140_稳定婚姻_KEY
题目传送门 暴力直接对于每个点跑一遍二分图匹配,能拿四十分. 然而我们考虑正解. 对于一对Couple我们建♂->♀的一条边,对于一对曾经有恋情的情侣我们建♀->♂的一条边. 跑Tarja ...
- 【转载】Direct3D纹理映射
原文:Direct3D纹理映射 更详细的文章:DirectX中的纹理映射相关技术 (转) 创建纹理对象 1: HRESULT CreateTexture( 2: UINT Width,//宽度 ...
- 洛谷 P1876 开灯
传送门 这道题凭什么是! 就因为它代码短?! 还是我太菜了... 第$i$盏灯的开关与否只由其约数个数决定,又有约数公式: 当$n=p_1^{a_1}p_2^{a_2}...p_n^{a_n}$时,约 ...
- CF 987 D. Fair
D. Fair http://codeforces.com/contest/987/problem/D 题意: n个城镇m条道路,(保证没有重边,两个城镇间可以到达),每个城镇拥有的特产ai(可能多个 ...
- R的数据库访问-MySQL
目录 1 RMySQL 2 环境与安装 3 建立通信 1 RMySQL R作为一款数据分析的工具,,而MySQL是一款常用的开源关系型数据库软件,非常适用于中小型的数据存储,当二者相互结合时才能爆发出 ...
- mono for andorid第一个小应用
先上图 这个小应用根据两人的姓名算出两人的关系,当然仅仅娱乐. 本来想多写写,但是实在觉得没什么可写的,而且本人正处于感冒状态,脑袋不怎么灵光,所以就不写那么多废话了. 安装mono的话,就上吾乐吧软 ...
- 记录阿里云ECS(Centos7.4)安装mysql 8.0.X服务
#*.rpm介绍 大多数二进制rpm包都包含在名称中倒数第二个字段中编译rpm的体系结构..rpm软件包有那么几种 *.src.rpm 源程序包,要先通过编译才能安装 *.noarch.rpm 该包适 ...
- Qt-QML-电子罗盘
使用QML中的Canvas实现电子罗盘绘制,效果图如下 一个简单的电子罗盘,红色N极.其中中间飞机表示当前的指向, 还是比较简单的,直接上代码吧 /* 作者:张建伟 时间:2018年4月27日 简述: ...