在做光光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;
}