NOIP 2003 栈(卡特兰数||DFS)

题目描述

栈是计算机中经典的数据结构,简单的说,栈就是限制在一端进行插入删除操作的线性表。 
栈有两种最重要的操作,即pop(从栈顶弹出一个元素)和push(将一个元素进栈)。 
栈的重要性不言自明,任何一门数据结构的课程都会介绍栈。宁宁同学在复习栈的基本概念时,想到了一个书上没有讲过的问题,而他自己无法给出答案,所以需要你的帮忙。 

 

宁宁考虑的是这样一个问题:一个操作数序列,从1,2,一直到n(图示为1到3的情况),栈A的深度大于n。 

现在可以进行两种操作: 

1. 将一个数,从操作数序列的头端移到栈的头端(对应数据结构栈的push操作)
2. 将一个数,从栈的头端移到输出序列的尾端(对应数据结构栈的pop操作) 

使用这两种操作,由一个操作数序列就可以得到一系列的输出序列,下图所示为由1 2 3生成序列2 3 1的过程。(原始状态如上图所示) 

 

你的程序将对给定的n,计算并输出由操作数序列1,2,...,n经过操作可能得到的输出序列的总数。 

分析:

方法一:卡特兰数

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<cctype>
#include<cstring>
#include<utility>
#include<cstdlib>
#include<iomanip>
#include<iostream>
#include<algorithm>
#define Clear(x) memset(x,0,sizeof(x))
#define fup(i,a,b) for(int i=a;i<b;i++)
#define rfup(i,a,b) for(int i=a;i<=b;i++)
#define fdn(i,a,b) for(int i=a;i>b;i--)
#define rfdn(i,a,b) for(int i=a;i>=b;i--)
typedef long long ll;
using namespace std;
const int maxn = 1e2+7;
const int inf = 0x3f3f3f3f;
const double pi=acos(-1.0);
const double eps = 1e-8;
 
int main()
{
    int n;
    ll f=1;
    while(~scanf("%d",&n))
    {
        rfup(i,1,n) f=f*(i*4-2)/(i+1);
        cout<<f<<endl;
    }
    return 0;
}

方法二:记忆化搜索,x代表在操作数列中数的个数,y代表在栈在数的个数。

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<cctype>
#include<cstring>
#include<utility>
#include<cstdlib>
#include<iomanip>
#include<iostream>
#include<algorithm>
#define Clear(x) memset(x,0,sizeof(x))
#define fup(i,a,b) for(int i=a;i<b;i++)
#define rfup(i,a,b) for(int i=a;i<=b;i++)
#define fdn(i,a,b) for(int i=a;i>b;i--)
#define rfdn(i,a,b) for(int i=a;i>=b;i--)
typedef long long ll;
using namespace std;
const int maxn = 1e2+7;
const int inf = 0x3f3f3f3f;
const double pi=acos(-1.0);
const double eps = 1e-8;
ll f[maxn][maxn];
int n;
 
int read()
{
    char ch=getchar();int ret=0,f=1;
    while(ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){ret=ret*10+ch-'0';ch=getchar();}
    return f*ret;
}
 
ll DFS(int x,int y)
{
    if(f[x][y]) return f[x][y];
    if(x==0) return 1;
    if(y>0) f[x][y]+=DFS(x,y-1);
    f[x][y]+=DFS(x-1,y+1);
    return f[x][y];
}
 
int main()
{
    n=read();
    cout<<DFS(n,0)<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41311604/article/details/81535511