美文网首页
火车出站题解+卡特兰数用法小结

火车出站题解+卡特兰数用法小结

作者: 九除以三还是三哦 | 来源:发表于2019-06-05 12:36 被阅读0次
从出栈可能性了解到了卡特兰数,粗劣的做一下小结。时间超限,数组越界什么的总是很烦恼,继续噶油。
第二次修改,增加了判断出栈序列是否正确的分析。

大佬总结的很详细,前面一部分是转过来的。[https://www.cnblogs.com/SovietPower/p/7202443.html]

一.公式

卡特兰数一般公式

令h(0)=1,h(1)=1,catalan数满足递推式。h(n) = h(0)h(n-1)+h(1)h(n-2) + ... + h(n-1)h(0) (n>=2)。也就是说,如果能把公式化成上面这种形式的数,就是卡特兰数

组合公式

  Cn = C(2n,n) / (n+1)

(化简前 **h(n) = c(2n,n)-c(2n,n+1) (n=0,1,2,...) 证明

递归公式1

  h(n) = h(n-1)(4n-2) / (n+1)**

递归公式2

  h(n) = ∑(i=0 to n-1) h(i)h(n-i-1)*

二.应用

  • 二叉树的计数等,这个有时间整理吧

三、例题改错

题目描述:

铁路进行列车调度时,常把站台设计成栈式结构的站台,试问:
设有编号为1到n的n辆列车,顺序开入栈式结构的站台,则可能的出栈序列有多少种?

输入:

输入包含多组测试数据。每组为一个正整数n(1<=n<=20),表示有n辆列车。

输出:

输出可能的出栈序列有多少种。

原解:

# include <iostream>
using namespace std;

int times(int n)
{
int i=0;
long long sum=0;
if(n==1||n==0) return 1;
else if(n==2) return 2;
else  
{   
     while(i<n/2)
    {
sum+=times(n-i-1)*times(i);
i++; 
    }
if(n%2==0) return 2*sum;
else return 2*sum+times((n-1)/2)*times((n-1)/2);
}
}

int main()
{
int n;
while(cin>>n)
{
cout<<times(n)<<endl;
}
} 

这个使用递推公式2,一层一层往前递推回去再一层一层回来,造成程序比较复杂,在处理n=20的时候就溢出了。

改进后:

# include <iostream>
using namespace std;

int main()
{
    long long int ca[20]; ca[0]=1;
    for(int i=1;i<=20;i++)
    {
        ca[i]=ca[i-1]*(4*i-2)/(i+1);
    }
    int n;
    while(cin>>n)
    {
        cout<<ca[n]<<endl;
    }
} 

优化后的算法为从0开始,使用递推公式1,这样简化了许多!


一、例题分析

题目

火车编号为:1~9,且不重复。如:编号分别为“1”、“2”、“3”、“4”、“5”的5个火车顺序进站,那么进站序列为“12345”,全部进站后再顺序出站,则出站序列为“54321”,如果先进1,2,然后2出站,然后1出站,然后再3进站、出站,4进站、出站,5进站、出站,那么出站序列就为21345.

输入

int maxNum:进站的火车最大编号
char* pOutSeq:使用字符串表示火车出站序列

输出参数(指针指向的内存区域保证有效):

无。

返回值:

Int: 根据输入的进站序列判断,如果输入的出站序列是可能的,返回1,否则返回0;

分析:
由于进栈的顺序是由小到大的,所以出栈序列应该满足以下条件:对于序列中的任何一个数其后面所有比它小的数应该是倒序的

代码

#include <iostream>
#include <string.h>
#include <stack>
using namespace std;

int JudgeTrainSequence (int maxNum, char *pOutSeq){
    if(pOutSeq == NULL || maxNum <= 0){
        return 0;
    }
    int size = strlen(pOutSeq);
    stack<int> trainSeq;
    
    int index = 1;  //index用来标记推进去几个 
    for(int i = 0;i < size;){
        if(trainSeq.empty() || trainSeq.top() < pOutSeq[i] - '0'){
            trainSeq.push(index);  //如果不符合出栈顺序,那么一定存在某个数其后面所有比它小的数不是倒序的 ,index最终一定会大于len 
            ++index;
        }
        else{
            trainSeq.pop();
            ++i;
        }
    }
    if(!trainSeq.empty()){
        return 0;
    }
    return 1;
}

int main()
{
    char s[3];
    while(cin>>s)
    {
        cout<<JudgeTrainSequence(3,s)<<endl;
    } 
    
}

相关文章

  • 火车出站题解+卡特兰数用法小结

    从出栈可能性了解到了卡特兰数,粗劣的做一下小结。时间超限,数组越界什么的总是很烦恼,继续噶油。 第二次修改,增加了...

  • 卡特兰数

    CGY杯 火车出站(卡特兰数) Problem DescriptionCGY管理着一个火车站的调度问题,这个车站有...

  • Golang 实现卡特兰数

    Golang 实现卡特兰数 卡特兰数又称卡塔兰数,卡特兰数是组合数学中一个常出现在各种计数问题中的数列。前20项为...

  • 卡特兰数:hdu-2067 小兔的棋盘&&火车出栈问题

    卡特兰数,一串神奇的数字,1,2,5,14...... 首先了解一下卡特兰数. 卡特兰数(好像很有用的说) - C...

  • AVL

    LOG(n) 卡特兰数 叉姐

  • 数学 | 卡特兰数

    卡特兰数 定义 卡特兰数又称卡塔兰数,英文名Catalan number,是组合数学中一个常出现在各种计数问题中出...

  • 卡特兰数

  • 卡特兰数

    之前看算法导论时,讲了给定几个数字,能构造出几种二叉树,当时只想到排列组合的解决方法,极其复杂又不好记,过段时间还...

  • 卡特兰数

    https://zhuanlan.zhihu.com/p/31317307 火车进出栈问题和腾讯那道猜拳游戏是一样...

  • 卡特兰数

    卡特兰数是一种经典的组合数,经常出现在各种计算中,其前几项为 :1, 2, 5, 14, 42,132, 429,...

网友评论

      本文标题:火车出站题解+卡特兰数用法小结

      本文链接:https://www.haomeiwen.com/subject/mkpjxctx.html