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

来源:互联网 发布:淘宝购物没收到货退款 编辑:程序博客网 时间:2024/05/16 19:11

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 secondpair <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;}
0 0
原创粉丝点击