E29952 咒语序列
思路:
- 考虑对每个位置
,可能存在一个最大的 ,使得 为一个合法括号序列,如 ()(())中对应的最大的 为 , 时不存在这样的 。 - 考虑 dp:设
表示 的最长合法后缀括号序列。 - 从前到后扫一遍,维护一个栈,当
为 (时将压入,当 为 )时,若栈非空则为栈顶下标,然后弹栈,此时更新 。 - 答案即为
。时间复杂度为 。 - 如上面的例子中,
,答案为 。
代码:
cpp
#include <iostream>
#include <stack>
using namespace std;
int dp[30001];
stack<int> stk;
int main(){
int len, ans = 0;
string s;
cin >> s;
len = s.size();
s = " " + s;
for (int i = 1; i <= len; i++){
if (s[i] == '('){
stk.push(i);
} else {
if (!stk.empty()){
int cur = stk.top();
stk.pop();
dp[i] = dp[cur - 1] + (i - cur + 1);
ans = max(ans, dp[i]);
}
}
}
cout << ans;
return 0;
}