一,问题描述
X 星球特别讲究秩序,所有道路都是单行线。一个甲壳虫车队,共 16 辆车,按照编号先后发车,夹在其它车流中,缓缓前行。路边有个死胡同,只能容一辆车通过,是临时的检查站,如图所示。X 星球太死板,要求每辆路过的车必须进入检查站,也可能不检查就放行,也可能仔细检查。如果车辆进入检查站和离开的次序可以任意交错。那么,该车队再次上路后,可能的次序有多少种?为了方便起见,假设检查站可容纳任意数量的汽车。显然,如果车队只有 1 辆车,可能次序 1 种;2 辆车可能次序 2 种;3 辆车可能次序 5 种。现在足足有 16 辆车啊,亲!需要你计算出可能次序的数目。
二,答案提交
这是一个整数,请通过浏览器提交答案,不要填写任何多余的内容(比如说明性文字)。
三,答案代码
#作业三 出栈顺序
n=eval(input("请输入甲壳虫车队个数:"))
from scipy.special import comb
print(comb(2*n,n)-comb(2*n,n-1))
答案:35357670
四,题目解读
这道题其实问的就是出栈的顺序,可以把死胡同检查战理解为一个栈,车队的车辆理解为进栈的元素。很多小伙伴会以为如果有三个车的话会有3*2*1=6种可能,如果有四个车,则有4*3*2*1=24种可能,其实这就不对啦!因为你们理解错了栈的概念。现在,你跟我来理解,栈就是一个坑,元素(车)就是一本刚好能卡进坑里的书,进栈就是把书放进坑里,出栈就是把书从坑里拿出来,每次只能那最上边的书(因为最下边的没法拿出来),单行道理解为一次只可以放入一本书或只能拿出来一本书,检查站可以容纳很多车,就是坑很大,可以放很多书。如图来理解:
那么对于123,出栈顺序如下图:
咱们理解的六种里边唯独少了3,1,2,其实6种是所有的可能,但是里边有不符合现实情况的可能 ,那就是3,1,2。就是进1,进2,进3,出3,出1(无法出1,因为1在最下边,上边压着2),出2。很明显,这是无法实现的,但是这也是出栈的一种可能,只是无法实现。所以,到了这里你应该能够理解出栈啦!那么再看16辆车,总共有16*15*•••••*2*1种可能。但是如何排除里边不符合实际的可能呢?这其实就用到了卡兰特数啦!在卡兰特数里边,所有可能里包含出栈序列和混乱序列,(出栈序列:进和出相等;混乱序列,进和出不相等)。在出栈序列中符合实际的可能为合法出栈顺序,不符合实际的为非法出栈顺序,很显然,出栈顺序是合法与非法出栈顺序的和,那么有如下公式:合法出栈顺序为 :
具体公式理解我放在了下边公式推导部分,可以直接滑到那一部分再来看啦!!!
对于16辆车,那就是n=16(进栈元素个数),即C(32,16)-C(32,17)
五,代码解读
n=eval(input("请输入甲壳虫车队个数:")) #输入车辆个数即进栈元素个数 from scipy.special import comb #引入scipy库里的comb(组合),用于求排列组合数 print(comb(2*n,n)-comb(2*n,n-1)) #卡特兰数公式
手机端在评论区有完整内容
六,公式推导
题目描述
n 个元素进栈序列为:1,2,3,4,...,n,则有多少种出栈序列。
思路
我们将进栈表示为 +1,出栈表示为 -1,则 1 3 2 的出栈序列可以表示为:+1 -1 +1 +1 -1 -1。(出栈可能情况理解为这个出栈序列排列组合后共多少种情况,出栈序列和为0,混乱序列和不为0)
根据栈本身的特点,每次出栈的时候,必定之前有元素入栈,即对于每个 -1 前面都有一个 +1 相对应。因此,出栈序列的 所有前缀和(即前n项和) 必然大于等于 0,(理解:由于必定先进栈,才能出栈,假设n先个全部进栈,那么前n项必定都为+1,大于0,如果在出栈后有再进栈的,那么前n项必定有-1,因为在前n项中,最多前n个都为+1,前n个也可能有-1,但是在前n个中,-1数量不能多余+1,出不能大于进,要不没东西可出),并且 +1 的数量 等于 -1 的数量(这是整个出栈序列中,并不是前n项)。
接下来让我们观察一下 n = 3 的一种出栈序列:+1 -1 -1 +1 -1 +1。序列前三项和小于 0,显然这是个非法序列。
如果将 第一个 前缀和小于 0 的前缀,即前三项元素都进行取反(+1变-1),就会得到:-1 +1 +1 +1 -1 +1(这是一个混乱序列),此时有 3 + 1 个 +1 以及 3 - 1 个 -1,和不为0。
因为这个非法序列 的前缀和(前n项和)必然是 -1,且 -1 比 +1 多一个,取反后得到的混乱序列,-1 比 +1 少一个,则 +1 变为 n + 1 个,且 -1 变为 n - 1 个。进一步推广,对于 n 元素的每种非法序列的取反序列(混乱序列),都会对应一个含有 n + 1 个 +1 以及 n - 1个 -1 的序列。
即所有可能=出栈序列+混乱序列
出栈序列=合法序列+非法数列,
非法序列=非法序列取反序列(混乱序列的一种)
混乱序列>非法序列取反序列
(如-1-1-1-1-1-1) (如-1+1+1+1-1+1)
如何证明非法序列和非法序列取反序列是一一对应的?
假设非法序列为 A,对应的非法序列取反序列为 B(也是一个混合序列)。每个 A 只有一个"第一个前缀和(前n项和)小于 0 的前缀",所以每个 A 只能产生一个 B。而每个 B 想要还原到 A,就需要找到"第一个前缀和(前n项和)大于 0 的前缀",显然 B 也只能产生一个 A。
每个 B 都有 n + 1 个 +1 以及 n - 1 个 -1,因此 B 的数量为,相当于在长度为 2n 的序列中找到
n + 1
个位置存放 +1。相应的,非法序列取反序列的数量(即非法序列数量)也就为
出栈序列的总数量共有,相当于在2n个数列放n个+1或放n个-1。因此合法的出栈序列的数量为
此时我们就得到了卡特兰数的通项
结语:当然,在CSDN里边还有很多大神的其他解法,与我的不同,但是都能顺利解决问题,本博文写的极其不易,花了两天思考问题,如果你都过啦,希望给个赞,支持一下我继续写下去的动力,相关资料附赠到下边啦!对于手机端用户,代码解读在评论区啦!!!
卡兰特数:「算法入门笔记」卡特兰数 - 知乎 (zhihu.com)
Python实现排列组合:(19条消息) Python实现排列组合C(n,m) 和 A(n,m)_liulicuican的博客-CSDN博客_python 排列组合c
秒杀出栈次序视频:出栈顺序题极速秒杀【数据结构】_哔哩哔哩_bilibili
今日一笑:《幽默的人就是会逗人开心》
乘客a:这趟公交车可真暖和。乘客b:是啊,尤其是外面那么冷,刚上车好像钻被窝了一样。
乘客a:别扯了,你家被窝里有这么多人啊?