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

Codeforces 5C Longest Regular Bracket Sequence [贪心] [DP]

2016-10-12 08:03 435 查看
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”.

Sample Input

Input

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

Output

6 2

Input

))(

Output

0 1

Source

Codeforces Beta Round #5

大概就是求最长的子串是的括号匹配。

那么两种做法。

第一种贪心做法。

每次遇到‘(’cnt++,遇到‘)’cnt–,那么如果某次cnt < 0的话,start = i+1 , cnt = 0,如果某次cnt==0 ,说明从start 到 当前位置刚好构成匹配串,这时候对答案进行更新,统计相同长度字串出现次数。

第二种DP。

用stack来模拟左括号的情况。

那么dp[i] = dp[last-1] + i - last + 1;,表示从当前位置到上一个左括号构成一个匹配串。

边走边统计出现次数即可。

贪心:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<iomanip>
#include<ctime>
#include<climits>
#include<cctype>
#include<algorithm>
#define AUTO "%I64d"
using namespace std;
#define smax(x,tmp) x=max((x),(tmp))
#define smin(x,tmp) x=min((x),(tmp))
#define maxx(x1,x2,x3) max(max(x1,x2),x3)
#define minn(x1,x2,x3) min(min(x1,x2),x3)
typedef long long LL;
const int maxn = 1000005;
char s[maxn],ss[maxn];
#define len first
#define tot second
pair <int,int> work(char s[maxn])
{
int cnt = 0 , ret = 0;
int sum = 0;
int start = 0;
int lens = strlen(s);
for(int i=0;i<lens;i++)
{
if(s[i]=='(') sum++;
else sum--;
if(sum<0) start=i+1,sum=0;
else if(!sum)
{
if(i-start+1 > ret) ret=i-start+1,cnt=1;
else if(i-start+1 == ret) cnt++;
}
}
return make_pair(ret,cnt);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("long.in","r",stdin);
freopen("long.out","w",stdout);
#endif
scanf("%s",s);
int ans = 0 , cnt;
pair <int,int> tmp = work(s);
if(tmp.len > ans)
{
ans = tmp.len;
cnt = tmp.tot;
}
int lens = strlen(s);
for(int i=0;i<lens;i++) ss[i]=s[lens-i-1]=='('?')':'(';
tmp = work(ss);
if(tmp.len > ans)
{
ans = tmp.len;
cnt = tmp.tot;
}
if(ans) printf("%d %d",ans,cnt);
else printf("0 1");
return 0;
}


DP:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<iomanip>
#include<ctime>
#include<climits>
#include<cctype>
#include<algorithm>
#define AUTO "%I64d"
using namespace std;
#define smax(x,tmp) x=max((x),(tmp))
#define smin(x,tmp) x=min((x),(tmp))
#define maxx(x1,x2,x3) max(max(x1,x2),x3)
#define minn(x1,x2,x3) min(min(x1,x2),x3)
typedef long long LL;
const int maxn = 1000005;
char s[maxn];
int dp[maxn];
stack <int> sta;
int main()
{
#ifndef ONLINE_JUDGE
freopen("long.in","r",stdin);
freopen("long.out","w",stdout);
#endif
scanf("%s",s+1);
int ans = 0;
int cnt = 0;
int lens = strlen(s+1);
for(int i=1;i<=lens;i++)
if(s[i] == '(') sta.push(i);
else if(!sta.empty())
{
int tmp = sta.top(); sta.pop();
dp[i] = dp[tmp-1] + i - tmp + 1;
if(dp[i] > ans)
{
ans = dp[i];
cnt = 1;
}else if(dp[i] == ans) cnt++;
}
if(ans) printf("%d %d",ans,cnt);
else printf("0 1");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息