您的位置:首页 > 产品设计 > UI/UE

【CodeForces 5C】【贪心】【dp】Longest Regular Bracket Sequence

2016-10-12 10:16 579 查看

Longest Regular Bracket Sequence

Time Limit: 2000MS Memory Limit: 262144KB 64bit IO Format: %I64d & %I64u

Description

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”.

Samples

Input1

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

Output1

6 2

Input2

))(

Output2

0 1

Source

Codeforces Beta Round #5

这个题有两个做法,一个是贪心(很复杂),一个是dp(超简单),dp orz hzx

先说一下贪心,直接跑一遍是肯定过不了的,可以正反跑两边,遇到正括号就++,反括号就–,然后如果小于0就重置计数器,等于0就更新答案

但是这样子只能跑出来最大值,个数很萎,还要跑出最大值再根据这个来把数目跑出来,还要返回检验,感觉比较慢,写起来也很复杂吗,但是可以过

然后就是dp,这里运用栈来辅助,读入右括号事,自动去匹配前一个未匹配的左括号,然后和它匹配更新答案

代码见下,显示贪心,我写的很复杂不要吐槽了:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<set>
#include<queue>
#include<algorithm>
#include<vector>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<stack>
#define INF 2100000000
#define ll long long
#define clr(x)  memset(x,0,sizeof(x))
#define clrmax(x)  memset(x,127,sizeof(x))

using namespace std;

inline int read()
{
char c;
int ret=0;
while(!(c>='0'&&c<='9'))
c=getchar();
while(c>='0'&&c<='9')
{
ret=(c-'0')+(ret<<1)+(ret<<3);
c=getchar();
}
return ret;
}

int ans,tim,mx,now,sta,r,l,lt,rt;
char c,s[1000005];

void work(int x)
{
if(c=='(')now+=x;
else now-=x;
ans++;
if(now==0)mx=max(mx,ans);
if(now<0)
{
ans=0;
now=0;
}
}

int main()
{
freopen("in.txt","r",stdin);
while(c=getchar())
{
if(c!='('&&c!=')')break;
s[++sta]=c;
work(1);
}
ans=now=0;
for(int i=sta;i>=1;i--)
{
c=s[i];
work(-1);
}
if(mx==0)
{
cout<<"0 1";
return 0;
}
for(int i=1;i<=sta;i++)
{
c=s[i];
if(c=='(')l++;
else r++;
if(i<mx)continue;
int j=i-mx+1;
if(s[j]=='('&&s[i]==')'&&l-lt==r-rt)
{
int now=0,b=1;
for(int k=j;k<=i;k++)
{
if(s[k]=='(')now++;
else now--;
if(now<0)
{
b=0;
break;
}
}
if(b)
{
int temp=i;
c=s[j];
if(c=='(')lt++;
else rt++;
for(i=temp+1;i<=temp+mx;i++)
{
j=i-mx+1;
c=s[i];
if(c=='(')l++;
else r++;
c=s[j];
if(c=='(')lt++;
else rt++;
}
tim++;
i--;
continue;
}

}
c=s[j];
if(c=='(')lt++;
else rt++;

}
cout<<mx<<' '<<tim;
return 0;
}


接着是dp:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<set>
#include<queue>
#include<algorithm>
#include<vector>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<stack>
#define INF 2100000000
#define ll long long
#define clr(x)  memset(x,0,sizeof(x))
#define clrmax(x)  memset(x,127,sizeof(x))

using namespace std;

inline int read()
{
char c;
int ret=0;
while(!(c>='0'&&c<='9'))
c=getchar();
while(c>='0'&&c<='9')
{
ret=(c-'0')+(ret<<1)+(ret<<3);
c=getchar();
}
return ret;
}

#define M 1000005

int f[M],mx,tim,n;
stack<int>S;

int main()
{
char c;
while(c=getchar())
{
n++;
if(c!='('&&c!=')')
{
if(mx)cout<<mx<<' '<<tim;
else cout<<"0 1";
return 0;
}
if(c=='(')S.push(n);
else
{
if(!S.empty())
{
int t=S.top();S.pop();
f
=f[t-1]+n-t+1;
if(f
>mx)
{
mx=f
;
tim=1;
}
else if(f
==mx)tim++;
}

}
}
}


大概就是这个样子,如果有什么问题,或错误,请在评论区提出,谢谢。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息