zoukankan      html  css  js  c++  java
  • 出栈序列的求解方法

    卡特兰数的概念

    假如现在有这么一个问题:

    一个序列从1到n依次入栈,那么可能的出栈序列一共有多少种?
    
    注意:在任意一个时刻,只要栈不为空,就可能有元素出栈,不是说元素全部入栈之后再出栈。
    

    这个问题的解其实等同于求n阶的卡特兰数(catalan)

    卡特兰数指的是在一个n*n的方格中,从左下角走到右上角。每一步只能往右或者往上,且在走的过程中不能越过从左下角到右上角的那条对角线。
    
    和入栈出栈问题对比可以发现,这里的往右走就相当于入栈,往上走就相当于出栈,对角线上的点就相当于栈为空的时候, 不能越过对角线就是说在栈为空的时候不能执行弹栈操作。
    

    出栈序列的求解方法

    既然往右相当于入栈, 往上相当于出栈,那么从左下角到右上角的路径即为对应的入栈出栈操作序列,我们可以执行全部的操作序列来获取全部的出栈序列。所以求解出栈序列的个数,只需求出搜索路径有多少个。

    当栈深度为4时,所有可能的搜索路径(入栈出栈操作序列):

    那么搜索又要如何实现?

    首先合理的搜索需要满足两个前提:

    • 每一步只能往右或者往上
    • 且在走的过程中不能越过从左下角到右上角的那条对角线

    搜索的递归实现:

    • 从某点开始的后续搜索,可以由其上方点的后续搜索和其右方点的后续搜索组成。
    #include <stdio.h>
    #include <stdlib.h>
    
    void catalan(int push, int pop, int n, char *order) {
        int index = push + pop;
        if (push == pop && pop == n) {
            order[index] = '';
            printf("%s
    ", order);
        }
        if (push < n) {
            order[index] = 'i';
            catalan(push + 1, pop, n, order);
        }
        if (pop < push) {
            order[index] = 'o';
            catalan(push, pop + 1, n, order);
        }
    }
    
    int main() {
        // n个数入栈
        int n;
        scanf("%d", &n);
        // 入栈出栈操作序列长为2n;
        char *order = calloc(2 * n + 1, sizeof(char));
        // 输出所有的入栈出栈操作序列
        catalan(0, 0, n, order);
        free(order);
        return EXIT_SUCCESS;
    }
    

    参考链接

    [1] https://www.jianshu.com/p/7d3604dfb8ba

  • 相关阅读:
    [BZOJ 1907] 树的路径覆盖 【树形DP】
    [BZOJ 1221] [HNOI2001] 软件开发 【费用流 || 三分】
    SoapUI:mock service的使用
    SoapUI:使用Excel进行参数化
    SoapUI:入门实例
    loadrunner Analysis :SLA(Service Level Agreement服务水平协议)
    loadrunner controller:实时查看VUser的运行情况
    loadrunner controller:设置多个load generator
    loadrunner controller:集合点策略
    loadrunner:web services接口测试
  • 原文地址:https://www.cnblogs.com/zzzz76/p/10409874.html
Copyright © 2011-2022 走看看