题目描述
这是另一道处理合法括号序列的题目。
我们应该提醒你,如果一个括号序列插入“+”和“1”后,可以得到一个正 确的数学表达式,那么它被称为“合法”的。
例如,序列“(())()”,“()”和“(()(()))”是合法的,但“)(”,“(()”和“(()))(”不是。
给出一个由“(”和“)”字符组成的字符串。你要找出它最长的是合法括号序列的子串,也同样要找出最长子串的个数。
题解
括号题容易想到栈,把左括号压进去,右括号会跟栈顶的左括号匹配,然后这个左括号会跟它位置-1的合法括号序列拼起来,所以记一个DP即可
代码
#include <bits/stdc++.h>
#define maxn 2000005
using namespace std;
int n,f[maxn],mx,ans;
stack<int> S;
char c[maxn];
int main(){
scanf("%s",c+1); n=strlen(c+1);
for(int i=1;i<=n;i++){
if(c[i]=='(') S.push(i);
else if(!S.empty()){
f[i]=f[S.top()-1]+i-S.top()+1; mx=max(mx,f[i]);
S.pop();
}
}
for(int i=1;i<=n;i++){
if(f[i]==mx) ans++;
}
if(mx==0) puts("0 1");
else printf("%d\n%d\n",mx,ans);
return 0;
}