洛谷 P1044 栈 (栈混洗,卡特兰数)

  • 1n1\sim n,问出栈可能的序列数

记忆化搜索/递归

#include<iostream>
#include<cstdio>
#define MAXN 20
using namespace std;
typedef long long ll;
int n;
ll f[MAXN][MAXN];
ll dfs(int i,int j){
    if(f[i][j])return f[i][j]; // i:队列中的个数, j:栈中的个数
    if(i==0)return 1;
    if(j>0)f[i][j]+=dfs(i,j-1); // 选择出栈
    f[i][j]+=dfs(i-1,j+1); // 选择队列中的数入栈
    return f[i][j];
}
int main(){
#ifdef WINE
    freopen("data.in","r",stdin);
#endif
    scanf("%d",&n);
    printf("%lld",dfs(n,0));
    return 0;
}

递推/DP

#include<iostream>
#include<cstdio>
#define MAXN 30
using namespace std;
typedef long long ll;
int n;
ll f[MAXN][MAXN];
int main(){
#ifdef WINE
    freopen("data.in","r",stdin);
#endif
    scanf("%d",&n);
    for(int i=0;i<=n;i++)f[0][i]=1; // 队列中0元素,栈中i个元素
    for(int i=1;i<=n;i++)
        for(int j=0;j<=n-i;j++){
            if(j>0)f[i][j]+=f[i][j-1];
            f[i][j]+=f[i-1][j+1];
        }
    printf("%lld",f[n][0]);
    return 0;
}

卡特兰数

  • f[n]=f[0]*f[n-1]+f[1]*f[n-2]+...+f[n-1]*f[0]
#include<iostream>
#include<cstdio>
#define MAXN 30
using namespace std;
typedef long long ll;
int n;
ll f[MAXN];
int main(){
#ifdef WINE
    freopen("data.in","r",stdin);
#endif
    scanf("%d",&n);
    f[0]=f[1]=1;
    for(int i=2;i<=n;i++)
        for(int j=0;j<i;j++)
            f[i]+=f[j]*f[i-j-1];
    printf("%lld",f[n]);
    return 0;
}

  • h[n]=h[n-1]*(4*n-2)/(n+1)
#include<iostream>
#include<cstdio>
#define MAXN 30
using namespace std;
typedef long long ll;
int n;
ll f[MAXN];
int main(){
#ifdef WINE
    freopen("data.in","r",stdin);
#endif
    scanf("%d",&n);
    f[0]=f[1]=1;
    for(int i=2;i<=n;i++)
        f[i]=f[i-1]*(4*i-2)/(i+1);
    printf("%lld",f[n]);
    return 0;
}

  • h[n]=C(2n,n)/(n+1)
  • C(m,n)=C(m-1,n-1)+C(m-1,n)
#include<iostream>
#include<cstdio>
#define MAXN 30
using namespace std;
typedef long long ll;
ll c[MAXN*2][MAXN];
int n;
int main(){
#ifdef WINE
    freopen("data.in","r",stdin);
#endif
    scanf("%d",&n);
    for(int i=1;i<=2*n;i++){
        c[i][0]=c[i][i]=1;
        for(int j=1;j<i;j++)
            c[i][j]=c[i-1][j]+c[i-1][j-1];
    }
    printf("%lld",c[2*n][n]/(n+1));
    return 0;
}

  • h[n]=C(2n,n)-C(2n,n-1)
#include<iostream>
#include<cstdio>
#define MAXN 30
using namespace std;
typedef long long ll;
int n;
ll c[MAXN*2][MAXN];
int main(){
#ifdef WINE
    freopen("data.in","r",stdin);
#endif
    scanf("%d",&n);
    for(int i=1;i<=2*n;i++){
        c[i][0]=c[i][i]=1;
        for(int j=1;j<i;j++)
            c[i][j]=c[i-1][j-1]+c[i-1][j];
    }
    printf("%lld",c[2*n][n]-c[2*n][n-1]);
    return 0;
}

posted @ 2020-08-24 00:25  winechord  阅读(206)  评论(0编辑  收藏  举报