C-Longest Regular Bracket Sequence (thinking + bracket matching + dp)

I ran into this question in the Guangguang oj competition.. I found it was the original question of Dao cf.

Idea: First, we must solve the problem of bracket matching, that is, use stack simulation to see if there is (correspondence. If there is, you need to record the longest number of substrings owned by this point, you need to update dp. dp[i]= max(dp[i],dp[pos(top position)-1]+(i-top+1)/2]; then dynamically update the number of maximum values.

#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;
}

 

Guess you like

Origin blog.csdn.net/zstuyyyyccccbbbb/article/details/112912084