zoukankan      html  css  js  c++  java
  • BZOJ4350: 括号序列再战猪猪侠

    Description

    括号序列与猪猪侠又大战了起来。
    众所周知,括号序列是一个只有(和)组成的序列,我们称一个括号
    序列S合法,当且仅当:
    1.( )是一个合法的括号序列。
    2.若A是合法的括号序列,则(A)是合法的括号序列。
    3.若A,B是合法的括号序列,则AB是合法的括号序列。
    我们考虑match[i]表示从左往右数第i个左括号所对应的是第几个右
    括号,现在他得到了一个长度为2n的括号序列,给了你m个信息,第i
    个信息形如ai,bi,表示match[ai]<match[bi],要你还原这个序列。
    但是你发现这个猪猪侠告诉你的信息,可能有多个括号序列合法;甚
    至有可能告诉你一个不存在合法括号序列的信息!
    你最近学了取模运算,你想知道答案对998244353(7*17*2^23+1)取
    模的结果,这个模数是一个质数。
     
     
     
     
     
     

    Input

    第一行一个正整数T,T< = 5,表示数据组数。
    对于每组数据,第一行一个n,m,n表示有几个左括号,m表示信息数。
    接下来m行,每行两个数ai,bi,1< = ai,bi< = n。
     

    Output

    对于每组数据,输出一个数表示答案。
     

    Sample Input

    5
    1 0
    5 0
    3 2
    1 2
    2 3
    3 2
    2 1
    2 3
    3 3
    1 2
    2 3
    3 1

    Sample Output

    1
    42
    1
    2
    0

    HINT

     对于前两个点,是卡特兰数的情况。


    对于第三个点,合法的情况只可能是 ()()()。

    对于第四个点,合法情况可能是 (()()) 或者 (())()

    对于第五个点,由于拓扑关系形成了环,显然无解。

     

    对于 100% 的数据,保证 n < = 300
     
    设f[l][r]表示第l个括号到第r个括号的匹配方案。
    考虑l的右括号应在哪里,有两种转移:
    1.(.....)型:若区间[l+1,r]中没有任何一条诸如match[i]<match[l]的条件,则f[l][r]=f[l+1][r]。
    2.(...)...型:枚举分割位置p,类似判断条件,转移为f[l][r]+=f[l+1][p]*f[p+1][r]。
    为了O(1)完成判断,我们其实是在询问一个矩形内有没有点,用前缀和判判即可。
    #include<cstdio>
    #include<cctype>
    #include<queue>
    #include<cmath>
    #include<bitset>
    #include<cstring>
    #include<algorithm>
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define ren for(int i=first[x];i;i=next[i])
    using namespace std;
    inline int read() {
        int x=0,f=1;char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    typedef long long ll;
    const int maxn=310;
    const int mod=998244353;
    int f[maxn][maxn],A[maxn][maxn];
    int check(int x1,int x2,int y1,int y2) {
        return A[x2][y2]-A[x1-1][y2]-A[x2][y1-1]+A[x1-1][y1-1];
    }
    int dp(int l,int r) {
        int& ans=f[l][r];
        if(ans>=0) return ans;
        if(l>=r) return ans=1;ans=0;
        if(!check(l+1,r,l,l)) ans=dp(l+1,r);
        rep(i,l,r-1) if(!check(l+1,i,l,l)&&!check(l,l,i+1,r)&&!check(l+1,i,i+1,r)) {
            (ans+=((ll)dp(l+1,i)*dp(i+1,r))%mod)%=mod;
        }
        return ans;
    }
    int main() {
        dwn(T,read(),1) {
            memset(f,-1,sizeof(f));
            memset(A,0,sizeof(A));
            int n=read(),m=read();
            while(m--) {
                int a=read(),b=read();
                A[b][a]=1;if(a==b) f[1][n]=0;
            }
            rep(i,1,n) rep(j,1,n) A[i][j]+=A[i][j-1]+A[i-1][j]-A[i-1][j-1];
            printf("%d
    ",dp(1,n));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Django---Blog系统开发之注册页面(验证码&ajax发送文件)
    Django---Blog系统开发之建库
    Eclipse下导入外部jar包的3种方式
    linux 下 .sh 文件语法
    热备,冷备,云备的区别
    plsql 中如何清除曾经登录过的用户名
    Mac 查看python安装路径
    mac terminal终端怎么退出python命令行
    PyCharm 2017 Mac 免注册版破解安装说明
    PL/SQL恢复默认窗口样式
  • 原文地址:https://www.cnblogs.com/wzj-is-a-juruo/p/5089768.html
Copyright © 2011-2022 走看看