(CodeForces - 5C)Longest Regular Bracket Sequence(dp+栈)(最长连续括号模板)

(CodeForces - 5C)Longest Regular Bracket Sequence

time limit per test:2 seconds
memory limit per test:256 megabytes
input:standard input
output:standard output

This is yet another problem dealing with regular bracket sequences.

We should remind you that a bracket sequence is called regular, if by inserting «+» and «1» into it we can get a correct mathematical expression. For example, sequences «(())()», «()» and «(()(()))» are regular, while «)(», «(()» and «(()))(» are not.

You are given a string of «(» and «)» characters. You are to find its longest substring that is a regular bracket sequence. You are to find the number of such substrings as well.

Input

The first line of the input file contains a non-empty string, consisting of «(» and «)» characters. Its length does not exceed 106.

Output

Print the length of the longest substring that is a regular bracket sequence, and the number of such substrings. If there are no such substrings, write the only line containing “0 1”.

Examples

input

)((())))(()())

output

6 2

input

))(

output

0 1

 

题目意思:

题目的意思就是给你一个小括号的字符串,问你最长的合法括号序列的长度是多少?和有几个这样合法的最长的括号序列

比如:

((())) 这个长度是6,3个左3个右

又比如样例:

((()))(()())

所以样例的最长长度是6,有两个这样的最长长度的括号段

 

做法:利用栈进行括号的匹配,加上dp数组记录

dp[i]:位置为i的右括号")"结尾的最长合法括号子序列的长度

dp[i]=dp[temp-1]+i-(temp-1)

其中temp表示与位置为i的右括号匹配的左括号的位置(栈记录了)

 

code:

 

#include <iostream>
#include <stdio.h>
#include<memory>
#include<stack>
#include<string.h>
#include<algorithm>
using namespace std;
#define max_v 1000005
int dp[max_v];//位置为i的右括号结尾的最长合法括号子序列的长度
//状态转移方程:dp[i]=dp[tmp-1]+i-tmp+1
stack<int> s;
int main()
{
    while(!s.empty())
        s.pop();
    string str;
    cin>>str;
    int l=str.size();
    int ans=0,sum=0;
    for(int i=0; i<l; i++)
    {
        if(str[i]=='(')
            s.push(i);
        else
        {
            if(!s.empty())
            {
                int temp=s.top();
                s.pop();
                if(temp)
                    dp[i]=dp[temp-1]+i-temp+1;
                else
                    dp[i]=dp[0]+i-temp+1;
                if(ans<dp[i])
                {
                    ans=dp[i];
                    sum=1;
                }
                else if(ans==dp[i])
                {
                    sum++;
                }
            }
        }

    }
    if(ans==0)
    {
        sum=1;
    }
    printf("%d %d\n",ans,sum);
    return 0;
}
/*
题目意思很简单,就是给以一串括号,要求最长合法括号子序列。

这是典型的括号题,括号题一般都可以用栈+dp解决。

设dp[i]表示位置为i的右括号结尾的最长合法括号子序列的长度,则易得:

dp[i]=dp[tmp-1]+i-tmp+1,其中tmp表示与位置为i的右括号匹配的左括号的位置(可以用栈记录)。

*/

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值