九度oj 题目1337:寻找最长合法括号序列
- 题目描述:
-
给你一个长度为N的,由’(‘和’)’组成的括号序列,你能找出这个序列中最长的合法括号子序列么?合法括号序列的含义便是,在这个序列中,所有的左括号都有唯一的右括号匹配;所有的右括号都有唯一的左括号匹配。例如:((()))()()便是一个长度为10的合法括号序列,而(()))( 则不是。需要你求解的是,找出最长的合法括号子序列的长度,同时找出具有这样长度的序列个数。
- 输入:
-
测试数据包括多个,每个测试数据包含两行:第一行为一个整数N,其中N不会超过10^6。第二行为一个长度为N的字符串,这个字符串由左括号'('和右括号')'组成。
- 输出:
- 对应每个测试案例,输出一行,其中包含两个整数,分别代表最长合法括号序列的长度和个数,中间由空格隔开。若没有合法的子序列存在,则返回0 1。
- 样例输入:
-
6 (())() 3 ))(
- 样例输出:
-
6 1 0 1
这道题开始我想简单了,结果一开始提交错误。后来采用动态规划的办法,代码如下1 #include <iostream> 2 #include <cstring> 3 #include <stdio.h> 4 #include <stdlib.h> 5 using namespace std; 6 7 char str[1000002]; 8 int cnt[1000002]; 9 int n; 10 int main(int argc,char* argv[]) 11 { 12 while(scanf("%d %s",&n,str)!= EOF) { 13 14 int temp = 0; 15 int len = strlen(str); 16 memset(cnt, 0, sizeof(cnt)); 17 for(int i = 0; i < len; i++) { 18 if(str[i] == '(') { 19 temp++; 20 } 21 else if(str[i] == ')') { 22 temp--; 23 if(temp < 0) { 24 temp = 0; 25 } 26 else { 27 if(i-1 == 0) { 28 cnt[i] = 2; 29 } 30 else { 31 if(str[i-1] == '(') { 32 cnt[i] = cnt[i-2] + 2; 33 } 34 else if(str[i-1] == ')') { 35 cnt[i] = cnt[i-1] + 2; 36 if(i - cnt[i] >= 0) { 37 cnt[i] = cnt[i-cnt[i]] + cnt[i]; 38 } 39 } 40 } 41 } 42 43 44 } 45 } 46 int maxCnt = 0; 47 int maxHap = 0; 48 49 for(int i = 0; i < len; i++) { 50 if(maxCnt < cnt[i]) { 51 maxCnt = cnt[i]; 52 maxHap = 1; 53 } 54 else if(maxCnt == cnt[i]) { 55 maxHap++; 56 } 57 } 58 if(maxCnt != 0) { 59 printf("%d %d\n",maxCnt, maxHap); 60 } 61 else { 62 printf("%d %d\n",0, 1); 63 } 64 65 } 66 return 0; 67 }
其中,cnt[i]表示第i个位置的合法序列长度为多长