(CodeForces

来源:互联网 发布:淘宝店铺装模板 编辑:程序博客网 时间:2024/06/16 21:07

(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

题目大意:题目意思很简单,就是给以一串括号,要求最长合法括号子序列。

思路:这个题目可以从两种角度考虑。
方法一:这是典型的括号题,括号题一般都可以用栈+dp解决。设f[i]表示位置为i的右括号结尾的最长合法括号子序列的长度,则易得:
f[i]=f[tmp-1]+i-tmp+1,其中tmp表示与位置为i的右括号匹配的左括号的位置(可以用栈记录)。
方法二:贪心。我们从左到右依次扫一遍括号串,碰到左括号cnt++,碰到右括号,并且此时cnt不为0,则说明该右括号有与之匹配的左括号,是合法的,记vis[i]为1;同理再从右到左扫一遍括号,记录合法的左括号,令vis[i]为1。而我们要做的就是统计连续1出现的个数的最大值,这只要从左到右扫一遍即可,所以该算法是O(n)的。

栈+dp实现代码

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

贪心实现代码

#include<cstdio>#include<cstring>using namespace std;const int maxn=1000005;char s[maxn];bool vis[maxn];int main(){    scanf("%s",s);    int len=strlen(s);    int cnt=0;    memset(vis,false,sizeof(vis));    for(int i=0;i<len;i++)    {        if(s[i]=='(') cnt++;        if(s[i]==')')        {            if(cnt)            {                vis[i]=true;                cnt--;            }        }    }    cnt=0;    for(int i=len-1;i>=0;i--)    {        if(s[i]==')') cnt++;        if(s[i]=='(')        {            if(cnt)            {                vis[i]=true;                cnt--;            }         }    }    int ans=0,sum=0;//ans表示最长匹配括号串的括号个数,sum表示最长匹配括号串一共有几个     cnt=0;    for(int i=0;i<len;i++)    {        if(vis[i]) cnt++;        else cnt=0;        if(ans<cnt) ans=cnt,sum=1;        else if(ans==cnt) sum++;    }    if(ans==0) sum=1;//没找到匹配括号串,则按题目要求给sum赋值1    printf("%d %d\n",ans,sum);    return 0; }
原创粉丝点击