C - Longest Regular Bracket Sequence(思维+括号匹配+dp)

在做光光oj的比赛碰到了这题..发现是道cf的原题。

思路:首先要解决括号匹配的问题,也就是用stack模拟,看当前的)有无(对应。有的话需要记录到这个点的拥有的最长子串数,需要dp更新。dp[i]=max(dp[i],dp[pos(top的位置)-1]+(i-top+1)/2];然后动态更新最值的个数。

#include<iostream>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=1e6+1000;
typedef long long LL;
inline LL read()
{
	LL x=0,f=1;char ch=getchar();
	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
	while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
typedef pair<char,int>P;
stack<P>s1,s2;
LL dp[maxn];
int main(void)
{
  cin.tie(0);std::ios::sync_with_stdio(false);
  string s=" ";string c;cin>>c;
  s=s+c;
  LL maxlen=0;LL sum=0;
  s1.push({s[1],1});
  for(int i=2;i<=s.size();i++){
    if(s[i]==')'){
        if(!s1.empty()&&s1.top().first=='('){
            LL pos=s1.top().second;
            if(!s1.empty()) s1.pop();
            dp[i]=max(dp[pos-1]+(i-pos+1)/2,dp[i]);
        ///    cout<<"dp["<<i<<"]="<<dp[i]<<endl;
            if(dp[i]>maxlen){
                maxlen=dp[i];
                sum=1;
            }
            else if(dp[i]==maxlen){
                sum++;
            }
        }
        else s1.push({s[i],i});
    }
    else s1.push({s[i],i});
  }
  if(maxlen==0){
    cout<<"0"<<" "<<"1"<<endl;
  }
  else cout<<maxlen*2<<" "<<sum<<endl;
return 0;
}

猜你喜欢

转载自blog.csdn.net/zstuyyyyccccbbbb/article/details/112912084