题意:
给你一个括号序列,让你找到最长的连续的合法括号序列
然后让你输出这个括号序列的长度是多少
这么长的括号序列一共有多少个
思路:
看到括号匹配,就用stack来弄就好了
然后我们dp一下,表示以这个字符结尾的序列的长度是多少
dp[i] += dp[k.top()-1]; 从当前合法序列的最左边'('的左边的位置转移,如果是'(',dp[k.top()-1]=0,否则 dp[k.top()-1]就是上一个合法序列的长度,比如:(())()就要加上4,当然也可能是0,比如:(()))()
正确题解(qscqesze,xiper):这是一道栈+dp的综合运用的题目。如果我们遇到(,那么我们就把这个位置放进栈里面。如果遇到)的话,就pop掉栈顶,且栈顶就是这个)匹配的(位置,如果我们用l[i]来表示与i匹配的左括号位置的话。
那么我们令dp[i]表示以i结尾的括号序列的最长长度的方程为:dp[i]=dp[l[i]-1]+(i-l[i]+1)。
最后在所有的dp里面取个max就好了。来自:http://www.cnblogs.com/qscqesze/p/6418555.html
代码:
1 //http://codeforces.com/problemset/problem/5/C 2 #include <bits/stdc++.h> 3 using namespace std; 4 typedef long long ll; 5 const int maxn = 1e6+10; 6 const int INF = 0x3f3f3f3f; 7 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL; 8 inline ll read(){ 9 ll x=0,f=1;char ch=getchar(); 10 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 11 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 12 return x*f; 13 } 14 ////////////////////////////////////////////////////////////////////////// 15 16 stack<int> k; 17 string s; 18 ll dp[maxn]; 19 20 int main(){ 21 cin >> s; 22 for(int i=0; i<s.size(); i++){ 23 if(s[i] == '(') 24 k.push(i); 25 else{ 26 if(!k.empty()){ 27 dp[i] = i-k.top()+1; 28 if(k.top() > 0) 29 dp[i] += dp[k.top()-1]; // 从当前合法序列的最左边'('的左边的位置转移 30 k.pop(); 31 } 32 } 33 } 34 // for(int i=0; i<s.size(); i++) 35 // cout << dp[i] << " "; 36 // cout << endl; 37 38 int ans1 = 0, ans2; 39 for(int i=0; i<s.size(); i++){ 40 if(dp[i] > ans1){ 41 ans1 = dp[i]; 42 ans2 = 1; 43 }else if(dp[i]==ans1){ 44 ans2 ++; 45 } 46 } 47 48 if(ans1 == 0) 49 cout << "0 1 "; 50 else 51 cout << ans1 << " " << ans2 << endl; 52 53 return 0; 54 }