从出栈可能性了解到了卡特兰数,粗劣的做一下小结。时间超限,数组越界什么的总是很烦恼,继续噶油。
第二次修改,增加了判断出栈序列是否正确的分析。
大佬总结的很详细,前面一部分是转过来的。[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;
}
}
网友评论