zoukankan      html  css  js  c++  java
  • [ Nowcoder Contest 165 #D ] 合法括号序列

    (\)

    (Description)


    键盘上有三个键,敲击效果分别是:

    • 在输出序列尾部添加一个左括号
    • 在输出序列尾部添加一个右括号
    • 删除输出序列尾部的第一个元素,若输出序列为空,则什么都不发生

    求恰好按键(N)次,输出序列是一个合法的括号序列的方案数对(P)取模的值。

    只要按键顺序或内容有一个位置不同就视为不同。

    • (Nin [1,10^3])(Pin [1,10^4]),不保证(P)为质数。

    (\)

    (Solution)


    神仙出题人神仙解法......

    • 首先有一个结论,对于一个长度确定的序列,其输出的方案数是确定的,且与具体每一个位置的内容无关。

      • 为什么呢?因为每一个位置输出是确定的,所以最后操作序列只需要改成符合要求的即可。

      • 于是我们先考虑求出输出一个长度为(i)的序列的方案数,设(f[i][j])表示一共按键(i)次,当前输出序列长度为(k)的方案数。转移就很自然,考虑是新加上一个还是删掉一个末尾的。因为序列确定,如果新加上的是输出序列,那么新加上的方案是唯一的,而删除就不需要确定末尾是什么了。注意退格键在输出序列为空时也可使用,有转移方程:

      [f[i][j]=(f[i-1][max(0,j-1)]+f[i-1][j+1] imes 2)\%mod ]

    • 然后就是考虑长度为(i)的合法序列方案数了,这不是(Catalan)吗!一个非质数打你脸上分解质因数太麻烦了,然后出题神仙就给出了神仙(DP)做法。设(g[i][j])为当前输出序列长度为(i),强制所有右括号合法,有(j)个左括号不合法的方案数。那么就有自然简单易懂直接的转移方程:

      [g[i][j]=(g[i-1][j+1]+(j>0?g[i-1][j-1]:0))\%mod ]

      代表新放一个右括号抵消掉一个左括号或新放一个左括号。

      [ans=sum_{i=0}^{lfloorfrac N 2 floor} f[n][i imes2] imes g[i imes 2][0] ]

    (\)

    (Code)


    #include<cmath>
    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #define R register
    #define N 1010
    using namespace std;
     
    int n,mod,ans,f[N][N],g[N][N];
     
    int main(){
      scanf("%d%d",&n,&mod);
      f[0][0]=1;
      for(R int i=1;i<=n;++i)
        for(R int j=0;j<=i;++j)
          f[i][j]=(f[i-1][j+1]+(j!=0?f[i-1][j-1]:0))%mod;
      g[0][0]=1;
      for(R int i=1;i<=n;++i)
        for(R int j=0;j<=i;++j)
          g[i][j]=(g[i-1][max(0,j-1)]+(g[i-1][j+1]<<1))%mod;
      for(R int i=0;i<=(n>>1);++i) (ans+=g[n][i<<1]*f[i<<1][0])%=mod;
      printf("%d
    ",ans);
      return 0;
    }
    
  • 相关阅读:
    再次或多次格式化导致namenode的ClusterID和datanode的ClusterID之间不一致的问题解决办法
    Linux安装aria2
    POJ 3335 Rotating Scoreboard 半平面交
    hdu 1540 Tunnel Warfare 线段树 区间合并
    hdu 3397 Sequence operation 线段树 区间更新 区间合并
    hud 3308 LCIS 线段树 区间合并
    POJ 3667 Hotel 线段树 区间合并
    POJ 2528 Mayor's posters 贴海报 线段树 区间更新
    POJ 2299 Ultra-QuickSort 求逆序数 线段树或树状数组 离散化
    POJ 3468 A Simple Problem with Integers 线段树成段更新
  • 原文地址:https://www.cnblogs.com/SGCollin/p/9664687.html
Copyright © 2011-2022 走看看