51Nod 1791 合法字符串 栈+动归
2017-08-23 15:30
281 查看
有一个括号序列,现在要计算一下它有多少非空子段是合法括号序列。
合法括号序列的定义是:
1.空序列是合法括号序列。
2.如果S是合法括号序列,那么(S)是合法括号序列。
3.如果A和B都是合法括号序列,那么AB是合法括号序列。
Input
多组测试数据。
第一行有一个整数T(1<=T<=1100000),表示测试数据的数量。
接下来T行,每一行都有一个括号序列,是一个由'('和')'组成的非空串。
所有输入的括号序列的总长度不超过1100000。
Output
输出T行,每一行对应一个测试数据的答案。
Sample Input
5
(
()
()()
(()
(())
Sample Output
0
1
3
1
2
拿到这道题比较棘手的原因来自于 如果A和B都是合法括号序列,那么AB是合法括号序列 这条规则,我们可以先不管这条规则,先处理符合前两条规则的,这就比较简单了,利用栈,我们是这样做的,用一个数组pos[i],初始化为-1,表示没有括号与之匹配,所以右括号的最终结果为-1,pos[a]=b;表示在a位置的这个左括号与b位置的有括号匹配,若pos[i]不等于-1.则在i位置的括号肯定为左括号。
我们以上找出了所有的独立括号,接下来就用到了动态规划的思想了,ans[i]表示已i开头的括号有多少合法的括号序列 状态转移方程:
ans[i] = ans[pos[i]+1] + 1 ( pos[i] != -1)
在纸上写写就明白了,最后所有符合3条规则的合法括号序列为ans[0]+ans[1]+ans[2]+......+ans[n-1];
分治也可以做这道题,不过我没看多懂
合法括号序列的定义是:
1.空序列是合法括号序列。
2.如果S是合法括号序列,那么(S)是合法括号序列。
3.如果A和B都是合法括号序列,那么AB是合法括号序列。
Input
多组测试数据。
第一行有一个整数T(1<=T<=1100000),表示测试数据的数量。
接下来T行,每一行都有一个括号序列,是一个由'('和')'组成的非空串。
所有输入的括号序列的总长度不超过1100000。
Output
输出T行,每一行对应一个测试数据的答案。
Sample Input
5
(
()
()()
(()
(())
Sample Output
0
1
3
1
2
拿到这道题比较棘手的原因来自于 如果A和B都是合法括号序列,那么AB是合法括号序列 这条规则,我们可以先不管这条规则,先处理符合前两条规则的,这就比较简单了,利用栈,我们是这样做的,用一个数组pos[i],初始化为-1,表示没有括号与之匹配,所以右括号的最终结果为-1,pos[a]=b;表示在a位置的这个左括号与b位置的有括号匹配,若pos[i]不等于-1.则在i位置的括号肯定为左括号。
我们以上找出了所有的独立括号,接下来就用到了动态规划的思想了,ans[i]表示已i开头的括号有多少合法的括号序列 状态转移方程:
ans[i] = ans[pos[i]+1] + 1 ( pos[i] != -1)
在纸上写写就明白了,最后所有符合3条规则的合法括号序列为ans[0]+ans[1]+ans[2]+......+ans[n-1];
分治也可以做这道题,不过我没看多懂
#include <stdio.h> #include <iostream> #include <algorithm> #include <string.h> #include <math.h> #include <string> #include <vector> #include <queue> #include <stack> #include <set> #include <map> using namespace std; typedef long long ll; const int MAXN=1100005; stack <int> s; ll dp[MAXN]; int pos[MAXN]; char ss[MAXN]; int main(void) { int T; scanf("%d",&T); while(T--) { while(!s.empty()) s.pop(); scanf("%s",ss); int len=strlen(ss); for(int i=0;i<=len+1;i++) { pos[i]=-1; dp[i]=0; } for(int i=0;i<len;i++) { if(ss[i]=='(') s.push(i); else{ 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; dp[i]=dp[pos[i]+1]+1; ans+=dp[i]; } printf("%lld\n",ans); } return 0; }
相关文章推荐
- 51Nod 1791 合法括号子段(栈+乱搞)
- 51nod 1791 合法括号子段
- 51nod 1791 合法括号子段 DP
- 51nod 1791 合法括号子段(DP)
- 51 Nod 1791 合法括号子段【分治+字符串】
- 51nod-1791-合法括号子段
- 51nod 1791 合法括号子段 (队列)
- 51nod 1791 合法括号子段 (dp)
- 51nod_1791——合法括号字段
- 合法括号子段 51Nod - 1791 **
- 51Nod-1791-合法括号子段
- 51nod 1791 合法括号子段
- 合法括号子段 51Nod - 1791 (栈+dp)
- 51NOD 1791 合法括号子段
- 51nod 1791 合法括号子段(模拟)
- 51nod 1277 字符串中的最大值【KMP算法】【next树】
- 51nod 贪心入门之一 完美字符串
- 51nod 1092 回文字符串 【巧用 dp】
- 字符串的合法验证
- 51nod 1451 合法三角形