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

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;
}
原创文章 152 获赞 15 访问量 6万+

猜你喜欢

转载自blog.csdn.net/ourfutr2330/article/details/52793837