1

您所在的位置:网站首页 出栈运算算法有哪些 1

1

2024-07-11 08:56| 来源: 网络整理| 查看: 265

方法一、

A.  1个元素入栈出栈一种可能记作f(1) = 1;

B.  2个元素入栈出栈有两种可能记f(2) = 2;

C. 3个元素入栈,考虑最后一个元素,出栈为第一个位置1种,第二个位置2种,第三个位置f(2)种,记作f(3) = 5;

D. 4个元素入栈,考虑最后一个元素,出栈为第一个位置1种,第二个位置(前面只有一个元素pop出去了,在3个push任意位置插入一个pop)有3种可能,第三个位置(说明已经pop出去两个元素,考虑1-3三个数,pop其中两个,若两个连续有前面f(2)种,不连续只有一种,即num_pop(1,2) = 2,num_pop(2,3)=2,num_pop(1,3)=1)有共5种可能,第四个位置pop即为前面f(3)的值,即f(4) = 1 + 3 + 5 + 5 = 14种。

E. 5个元素入栈,考虑最后一个元素,出栈为第一个位置1种,第二个位置(前面有4个元素选择一个pop)有4种可能,第三个位置(说明已有两个元素pop出去,若为pop的为1,2有2种,1,3有一种,1,4有1种,若pop的为2,3有2种,pop2,4有1种,pop3,4有2种)共计9种,第四个位置(说明已经pop出去三个元素,那么假设1未被pop,有f(3)种,2未被pop有f(2)种,3未被pop有f(2)种,4未被pop有f(3)种)共14种,第五个位置即f(4),因此f(5) = 1 + 4 + 9 + 14 + 14 = 42种。

方法二、

A.  f(4) = |push| x | x | x | x | x | x |pop|

B. f(5) = |push|pop| f(4) | + |push| push | x | x | x | x | x | x | x | pop |

显然 |push| push | x | x | x | x | x | x | x | pop | > f(4) ,由于对应于第一个x可以是pop,可以有pop多一个在前。

设为:|push|push| x1 | x2 | x3 | x4 | x5 | x6 | x7 |pop| x1一个pop不能让其产生消除第一个push

x2x1同时为pop时候,后面还有6个数即f(3) = 5种

x3消除第一个push是不可能的,不用考虑

x4和x1,x2,x3中两个个组合pop可以消除第一个push(但x1,x2同为pop不考虑)即有C(3)(2) - 1 = 2 种可能,而右边有4个空缺,有f(2) = 2种,综合考虑有2*2 = 4 种。

x5消除第一个push是不可能的,不用考虑

x6消除第一个push,若x5为push,那么必然不成立。因此x1-x4排列2push,2pop,有C(4)(2) - 1 = 5种,而对于后者只有x7只有push一种可能,综合考虑有5*1 = 5种

x7消除第一个push,不可能。

因此,f(5) = f(4) + f(4) + 5 + 4 + 5 = 14 * 3 = 42

方法三、

卡特兰数 h(n)=h(n-1)*(4*n-2)/(n+1) = C(2n,n)/(n+1)  = c(2n,n)-c(2n,n+1) 将5代入 直接得到答案42

证明:

1. 假设1~n的元素,中第i个元素最后出栈,那么在i之前的元素都在i入栈前已经完成了出栈,即有f(i-1)种。所有i之后的元素在i入栈后,先后完成了入栈和出栈,有f(n-i)种。

令f(0) = 1,那么有; f(n) = f(0)*f(n-1) + f(1)*f(n-2)……f(n-1)*f(0) 

2. 用0,1分别表示出栈和入栈,那么1~5的入栈出栈操作可以用10位01bit位来模拟,但需要保证从左边到右边扫描过程中,1个个数总是大于或等于0的个数。

假设采用枚举的方法,即C(2n,n)种,有哪些不符合要求?

假设某个偶数位2m,产生了冲突,前面0的个数超出1个个数,显然2m位是0,那么必须有2m-1位刚好匹配完所有的push,即1,0对等。显然奇数不可能实现这个,一次不可能在偶数位冲突。

假设某个奇数位2m+1产生冲突,那么前2m位刚好匹配,2m+1位是0,然后后面有n-m-1个0,n-m个1,,将后面的数据都对应反向,即n-m个0,n-m-1个1,仍不影响该结果不可能是合理解,在n-m+m+1 = n+1个0,n-1个1产生的组合包含n个0,n个1产生的不合理解。

n-1个1,n+1个0,组合成2n个bit的列,在某一位上0的个数会超过1的个数,假设这个位是偶数位,显然不可能,若为奇数为,设为2*x + 1,将后面数据都反向对应有n-x-1个0,n-x个1,完全也不影响这个列成为不符合要求的列,即有n-1个1,n+1个0组合不合理情况包含n个0,n个1产生的不合理解。

即n-1个1,n+1个0,产生的不合理解即为全部不合理解。

因此h(n) = c(2n,n) - c(2n,n+1);

方法四、

代码解决:

少量数据可以直接10位bit,每次+1,判断是否有5个1,判断是否从左到右边遍历总是1个数不小于0个数,符合即可输出结果。

也可以初始化5个1,5个0,然后在这个集合中next_permutation,求所有集合,然后对每种组合进行判断,代码如下。

#include #include #include using namespace std; int testify(int *a,int len) { int num0 = 0; int num1 = 0; for(int i=0;i num1) return 0; } return 1; } int main() { int m[10] = {0,0,0,0,0,1,1,1,1,1}; int count = 0; do{ if(testify(m,10)) ++count; }while(next_permutation(m,m+10)); cout


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3