题意:给一串括号序列,求出最长的合法序列的长度以及个数
思路:先求出长度,然后再用相同的办法统计出个数
定义dp[i]表示第i个位置的右括号结尾的合法序列的左边界
定义lef[i]表示第i个位置的右括号匹配到的左括号的位置
转移方程如下:
dp[i]=dp[lef[i]−1](s[lef[i]−1]==′)′)
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1000007;
char s[maxn];
int lef[maxn];
int dp[maxn];
stack <int> stk;
void Clear(){
while(! stk. empty())
stk. pop();
}
int main(){
while(~ scanf("%s", s)){
Clear();
int n = strlen(s);
for(int i = 0; i < n; i ++){
if(s[i] == '(')
stk. push(i);
if(s[i] == ')'){
if(stk. empty()){
lef[i] = -1;
dp[i] = -1;
continue;
}
int x = stk. top();
stk. pop();
dp[i] = lef[i] = x;
if(s[x - 1] == ')' && dp[x - 1] != -1)
dp[i] = dp[x - 1];
}
}
int ans = 0, num = 0;
for(int i = 0; i < n; i ++)
if(s[i] == ')' && dp[i] != -1)
ans = max(ans, i - dp[i] + 1);
for (int i = 0; i < n; i ++ )
if (s[i] == ')' && dp[i] != -1)
if(i - dp[i] + 1 == ans)
num ++;
if (ans)
printf("%d %d\n", ans, num);
else
puts("0 1");
}
return 0;
}