zoukankan      html  css  js  c++  java
  • 51Nod 1791 合法括号子段

    给定一串括号串,对于其中每个左括号‘(’最多只能找到一个与之相匹配的右括号‘)’。显然,在括号串固定的情况下,括号的匹配是固定不变的。根据题意,空串为合法括号,“()”为合法括号串,若A为合法括号串则”(A)”为合法括号串。那么我们可以先用括号匹配算法(利用栈)可以找出独立括号的配对情况。假设括号匹配对用数组pos[N]表示,初始化为-1,代表没有与之匹配的括号(右括号最终值是-1),pos[i]表示在第pos[i]个位置上的右括号与第i个左括号匹配。即若pos[i]≠−1,第i个位置上肯定是左括号,第pos[i]个位置上肯定是右括号。
    找出独立括号后,以每个括号为开头计算以该括号开头,能有多少对合法的括号序列。用ans[i]存储答案,ans[i]表示以第i个括号开始能有多少种合法的序列,状态转移方程:

    $$ans[i]=ans[pos[i]+1]+1  i!=-1$$
    最后$Ans=sum_{i=0}^{len-1}ans[i]$
    
    #include <bits/stdc++.h>
    using namespace std;
    
    #define ll long long
    #define F(i,a,b) for(int i=a;i<=b;++i)
    #define R(i,a,b) for(int i=a;i<b;++i)
    #define mem(a,b) memset(a,b,sizeof(a))
    const int N = 1100011;
    int t;
    char s[N];
    int pos[N];
    ll ans[N];
    stack<int>S;
    
    
    int main()
    {
        for(scanf("%d",&t);t--;)
        {
            scanf("%s",s);
            int len=strlen(s);
            R(i,0,len) pos[i]=-1,ans[i]=0;
            while(!S.empty()) S.pop();
            R(i,0,len)
            {
                if(s[i]=='(') { S.push(i);continue; }
                if(S.empty()) continue;
                pos[S.top()]=i;S.pop();
            }
            ll Ans=0;
            for(int i=len-1;i>=0;--i)
            {
                if(pos[i]==-1) continue;
                ans[i]=ans[pos[i]+1]+1;
                Ans+=ans[i];
            }
            printf("%I64d
    ",Ans );
        }
        return 0;
    }
    
  • 相关阅读:
    字符串与数字相互转换
    CodeForces
    解救迷茫的草滩小王子
    Ubuntu18.0.4 apt换源
    N进制与十进制之间的 转换(整数,小数)
    2019-10-10问题
    千里之行始于足下,付出总会有回报
    git--基本命令篇
    C#-网络请求方法
    爬虫实战-网易云音乐
  • 原文地址:https://www.cnblogs.com/chendl111/p/7283734.html
Copyright © 2011-2022 走看看