(CodeForces
来源:互联网 发布:淘宝店铺装模板 编辑:程序博客网 时间:2024/06/16 21:07
(CodeForces - 5C)Longest Regular Bracket Sequence
time limit per test:2 seconds
memory limit per test:256 megabytes
input:standard input
output:standard output
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”.
Examples
input
)((())))(()())
output
6 2
input
))(
output
0 1
题目大意:题目意思很简单,就是给以一串括号,要求最长合法括号子序列。
思路:这个题目可以从两种角度考虑。
方法一:这是典型的括号题,括号题一般都可以用栈+dp解决。设f[i]表示位置为i的右括号结尾的最长合法括号子序列的长度,则易得:
f[i]=f[tmp-1]+i-tmp+1,其中tmp表示与位置为i的右括号匹配的左括号的位置(可以用栈记录)。
方法二:贪心。我们从左到右依次扫一遍括号串,碰到左括号cnt++,碰到右括号,并且此时cnt不为0,则说明该右括号有与之匹配的左括号,是合法的,记vis[i]为1;同理再从右到左扫一遍括号,记录合法的左括号,令vis[i]为1。而我们要做的就是统计连续1出现的个数的最大值,这只要从左到右扫一遍即可,所以该算法是O(n)的。
栈+dp实现代码:
#include<cstdio>#include<cstring>#include<stack> using namespace std;const int maxn=1000005;char s[maxn];int f[maxn];stack<int> st; int main(){ scanf("%s",s+1); int ans=0,sum=0; int len=strlen(s+1); memset(f,0,sizeof(f)); for(int i=1;i<=len;i++) { if(s[i]=='(') st.push(i); else { if(!st.empty()) { int t=st.top(); st.pop(); f[i]=f[t-1]+i-t+1; if(ans<f[i]) ans=f[i],sum=1; else if(ans==f[i]) sum++; } } } if(ans==0) sum=1; printf("%d %d\n",ans,sum); return 0;}
贪心实现代码:
#include<cstdio>#include<cstring>using namespace std;const int maxn=1000005;char s[maxn];bool vis[maxn];int main(){ scanf("%s",s); int len=strlen(s); int cnt=0; memset(vis,false,sizeof(vis)); for(int i=0;i<len;i++) { if(s[i]=='(') cnt++; if(s[i]==')') { if(cnt) { vis[i]=true; cnt--; } } } cnt=0; for(int i=len-1;i>=0;i--) { if(s[i]==')') cnt++; if(s[i]=='(') { if(cnt) { vis[i]=true; cnt--; } } } int ans=0,sum=0;//ans表示最长匹配括号串的括号个数,sum表示最长匹配括号串一共有几个 cnt=0; for(int i=0;i<len;i++) { if(vis[i]) cnt++; else cnt=0; if(ans<cnt) ans=cnt,sum=1; else if(ans==cnt) sum++; } if(ans==0) sum=1;//没找到匹配括号串,则按题目要求给sum赋值1 printf("%d %d\n",ans,sum); return 0; }
- codeforces~~~
- Codeforces
- codeforces
- Codeforces
- codeforces
- codeforces
- Codeforces
- Codeforces
- CodeForces
- CodeForces
- CodeForces
- CodeForces
- CodeForces
- Codeforces
- Codeforces
- Codeforces
- Codeforces
- Codeforces
- [题解]bzoj2142 礼物
- Banner无限轮播
- 浅谈打印流是真的自动刷新吗?
- Java学习笔记(八)——多态
- ZK Hadoop Hive 集群搭建
- (CodeForces
- 看不懂的微信小程序 正在布局移动电商之路
- Kafka剖析(一):Kafka背景及架构介绍
- 扩欧理解ex_gcd
- jQuery选择器(1)
- Android CheckBox让文字在选择框的左边
- [P1134]阶乘问题
- dp基础6--[HDU-2859] 最大对称矩阵
- sprintf用法