• 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;
    }
    
  • 相关阅读:
    高手详解SQL性能优化十条经验
    大并发大数量中的MYSQL瓶颈与NOSQL介绍
    数据库索引的作用和优点缺点
    数据库优化方法整理
    Java中Date和Calender类的使用方法
    常用正则表达式大全 (转)
    java 反射的实例
    JAVA路径问题
    jsp ${param.id}用法
    jsp base标签与meta标签学习小结
  • 原文地址:https://www.cnblogs.com/chendl111/p/7283734.html
Copyright © 2020-2023  润新知