1791 合法括号子段

原创 2017年10月07日 18:23:58

1791 合法括号子段

Description

有一个括号序列,现在要计算一下它有多少非空子段是合法括号序列。

合法括号序列的定义是:

1.空序列是合法括号序列。
2.如果S是合法括号序列,那么(S)是合法括号序列。
3.如果A和B都是合法括号序列,那么AB是合法括号序列。

Input

多组测试数据。

第一行有一个整数T(1<=T<=1100000),表示测试数据的数量。

接下来T行,每一行都有一个括号序列,是一个由’(‘和’)’组成的非空串。

所有输入的括号序列的总长度不超过1100000。

Output

输出T行,每一行对应一个测试数据的答案。

Input示例

5
(
()
()()
(()
(())

Output示例

0
1
3
1
2

Solution

一道神奇的dp题,其实状态也很好想,因为对于其中每个‘(’最多只能找到一个与之相匹配的‘)’。显然,在括号串固定的情况下,括号的匹配是固定不变的。有了这个策略,我们就可以先用栈将括号匹配掉,p[i]表示与i这个括号相匹配的括号的位置,易得到dp方程 ans[i]=ans[p[i]+1]+1,再线扫一遍求和即可。

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int T,p[1100010],stuck[1100010],ans[1100010];
char ch[1100010];
int main(){
    scanf("%d",&T);
    while (T--){
        scanf("%s",ch+1);
        int l=strlen(ch+1),top=0;
        long long num=0;
        for (int i=1;i<=l;i++) p[i]=-1;
        for (int i=1;i<=l;i++){
            if (ch[i]=='(') stuck[++top]=i;
            else if (top) p[stuck[top--]]=i;
        }
        for (int i=l;i>=1;i--)
            if (p[i]==-1) ans[i]=0; else ans[i]=ans[p[i]+1]+1;
        for (int i=1;i<=l;i++)
            num+=ans[i];
        printf("%lld\n",num);
    }
    return 0;
}

51Nod-1791-合法括号子段

ACM模版描述题解这里,我们需要明确区分一个定义,什么叫做子段?什么叫做子序列?子段是子序列的一种,也叫做连续子序列,而子序列呢?如果不要求连续,则是可以从原序列中任意取,但是要保持原先的先后顺序即可...
  • f_zyj
  • f_zyj
  • 2017-07-31 11:40:09
  • 436

51nod 1791 合法括号子段 (dp)

Description 有一个括号序列,现在要计算一下它有多少非空子段是合法括号序列。 合法括号序列的定义是: 空序列是合法括号序列。 如果 S 是合法括号序列,那么...
  • qq_28954601
  • qq_28954601
  • 2017-09-23 10:33:26
  • 186

51nod 1791 合法括号子段(DP)

[1791 合法括号子段] 有一个括号序列,现在要计算一下它有多少非空子段是合法括号序列。 合法括号序列的定义是: 1.空序列是合法括号序列。 2.如果S是合法括号序列,那么(S)是合法括号序...
  • u012435889
  • u012435889
  • 2017-09-04 14:45:19
  • 166

51Nod 1791 合法字符串 栈+动归

有一个括号序列,现在要计算一下它有多少非空子段是合法括号序列。 合法括号序列的定义是: 1.空序列是合法括号序列。 2.如果S是合法括号序列,那么(S)是合法括号序列。 3.如果A和B都是合法...
  • GYH0730
  • GYH0730
  • 2017-08-23 15:30:56
  • 249

合法括号子段 51Nod - 1791 **

有一个括号序列,现在要计算一下它有多少非空子段是合法括号序列。 合法括号序列的定义是: 1.空序列是合法括号序列。 2.如果S是合法括号序列,那么(S)是合法括号序列。 3.如果A和B都是合法...
  • qq_36424540
  • qq_36424540
  • 2017-08-26 20:54:05
  • 92

51nod 1791 合法括号子段

分治 每层,处理左端点在左区间,右端点在右区间的情况下是数量。其总和就是答案。 #include using namespace std; const int MAXN=1100100; lon...
  • xin_jun
  • xin_jun
  • 2017-07-31 15:08:16
  • 83

51NOD 1791 合法括号子段

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1791用一个栈来维护,碰到左括号入栈,碰到右括号出栈, 出栈规则:栈顶不...
  • qq_33688997
  • qq_33688997
  • 2017-10-27 00:52:57
  • 55

51nod 1791 合法括号子段(模拟)

1791 合法括号子段 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题  收藏  关注 有一个括号序列,现在要计算一下它有多少非空子段是合法...
  • haut_ykc
  • haut_ykc
  • 2017-09-11 22:28:40
  • 87

合法括号子段 51Nod - 1791 (栈+dp)

有一个括号序列,现在要计算一下它有多少非空子段是合法括号序列。 合法括号序列的定义是: 1.空序列是合法括号序列。 2.如果S是合法括号序列,那么(S)是合法括号序列。 3.如果A和B都是合法...
  • SunMoonVocano
  • SunMoonVocano
  • 2017-08-23 21:58:39
  • 237

51nod 1791 合法括号子段 (队列)

每次匹配上一个,当前位置能匹配的括号数应该是左括号减一位置的括号数+1; 代码一看就懂,还自带stack函数,省的数组模拟了。 #include using namespace std; cha...
  • clx55555
  • clx55555
  • 2017-11-02 21:56:42
  • 176
收藏助手
不良信息举报
您举报文章:1791 合法括号子段
举报原因:
原因补充:

(最多只允许输入30个字)