题目链接:http://codeforces.com/problemset/problem/5/C
-----------------------------------------------------------------------------
题意:给一个括号序列,求满足括号匹配的最长子串长度和个数。
思路:用栈记录序列中的左括号位置,每当出现一个右括号,判断栈是否为空,若不为空,用此时右括号的位置i减去最近的左括号位置再+1即可得到串的长度。
注意:()(),在第二个括号之前已经有符合条件的串,要记录左括号之前的位置已经得到的串的长度。
状态转移方程为f[i]=f[t-1]+i-t+1。t表示离i最近的左括号的位置。
代码:
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<vector> #include<stack> #include<bitset> #include<cstdlib> #include<cmath> #include<set> #include<list> #include<deque> #include<map> #include<queue> using namespace std; typedef long long ll; const double PI = acos(-1.0); const double eps = 1e-6; const int MAXN =1e6+10; int len[MAXN]={0}; char s[MAXN]; stack<int>sta; int k = 0; int main(void){ scanf("%s",&s); int sl = strlen(s); int maxl =0; int cls=0; for(int i=0;i<sl;i++){ if(s[i]==‘(‘){ sta.push(i); }else{ if(!sta.empty()){ k = sta.top(); sta.pop(); if(k>0){ len[i]=len[k-1]+i-k+1; }else{ len[i]=i-k+1; } if(len[i]>maxl){ cls = 1; maxl = len[i]; }else if(len[i]==maxl){ cls++; } //printf("i:%d k:%d len:%d\n",i,k,len[i]); } } } if(maxl > 0) printf("%d %d\n",maxl,cls); else printf("%d %d\n",0,1); return 0; }