codeforces 5C Longest Regular Bracket Sequence

给一个括号序列,求满足括号匹配的最长子串长度和个数。


可以用栈来依次记录序列中的左括号位置,每当出现一个右括号,判断栈是否为空,若不为空,用此时右括号的位置i减去最近的左括号位置再+1即可得到串的长度。

需要注意的是这种情况:()(),在第二个括号之前已经有符合条件的串,这里需要记录左括号之前的位置已经得到的串的长度。设dp[i]表示到第i个右括号所获串的长度。

则dp[i]=dp[t-1]+i-t+1。t表示离i最近的那个左括号的位置。


#include
using namespace std;
char s[1000005];
int dp[1000005];
stack st;
int main()
{
    scanf("%s",s+1);
    int cnt=0,ans=0,i,l=strlen(s+1);
    for(i=1;i<=l;++i)
    {
        if(s[i]=='(') st.push(i);
        else
        {
            if(!st.empty())
            {
                int t=st.top();
                st.pop();
                dp[i]=dp[t-1]+i-t+1;
                if(dp[i]>ans)
                {
                    ans=dp[i];
                    cnt=1;
                }
                else if(dp[i]==ans) ++cnt;
            }
        }
    }
    if(!ans) cnt=1;
    printf("%d %d\n",ans,cnt);
    return 0;
}

看到这题还有另一种方法,空间复杂度要低一些。

就是:从前往后寻找匹配左括号的最长子串长度,再从后往前求匹配右括号的最长子串长度。取二者的最大值。

你可能感兴趣的:(codeforces 5C Longest Regular Bracket Sequence)