Description
We give the following inductive definition of a “regular brackets” sequence:
- the empty sequence is a regular brackets sequence,
- if s is a regular brackets sequence, then (s) and [s] are regular brackets sequences, and
- if a and b are regular brackets sequences, then ab is a regular brackets sequence.
- no other sequence is a regular brackets sequence
For instance, all of the following character sequences are regular brackets sequences:
(), [], (()), ()[], ()[()]
while the following character sequences are not:
(, ], )(, ([)], ([(]
Given a brackets sequence of characters a1a2 … an, your goal is to find the length of the longest regular brackets sequence that is a subsequence of s. That is, you wish to find the largest m such that for indices i1, i2, …, im where 1 ≤ i1 < i2 < … < im ≤ n, ai1ai2 … aim is a regular brackets sequence.
Given the initial sequence ([([]])]
, the longest regular brackets subsequence is [([])]
.
Input
The input test file will contain multiple test cases. Each input test case consists of a single line containing only the characters (
, )
, [
, and ]
; each input test will have length between 1 and 100, inclusive. The end-of-file is marked by a line containing the word “end” and should not be processed.
Output
For each input case, the program should print the length of the longest possible regular brackets subsequence on a single line.
Sample Input
((())) ()()() ([]]) )[)( ([][][) end
Sample Output
6 6 4 0 6
题目大意:就是寻找有多少对括号匹配,并输出它们的个数
解题思路:
两种括号的匹配问题,这个问题不能用顺序解决,因为两种括号存在交叉的情形,之前我们用队列的方法做过,而且有些情况并不能知道优先匹配哪种括号,但是今天不用队列方法,用DP
这个题目注意分段max(d[j][i+j-1],d[j][k]+d[k+1][j+i-1])
程序代码:
1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 char s[110]; 5 int d[110][110]; 6 bool match(char a, char b) 7 { 8 return (a == '(' && b == ')') || (a == '[' && b == ']'); 9 } 10 int max(int x,int y) 11 { 12 return x>y?x:y; 13 } 14 int main() 15 { 16 while(~scanf("%s",s)) 17 { 18 if(strcmp(s,"end")==0) break; 19 int len=strlen(s); 20 for(int i=0;i<len;i++) 21 { 22 d[i][i]=0; 23 if(match(s[i],s[i+1])) 24 d[i][i+1]=2; 25 else 26 d[i][i+1]=0; 27 } 28 for(int i=3;i<=len;i++) 29 for(int j=0;j+i-1<len;j++) 30 { 31 d[j][i+j-1]=0; 32 if(match(s[j],s[i+j-1])) 33 d[j][i+j-1]=d[j+1][i+j-2]+2; 34 for(int k=j;k<i+j-1;k++) 35 d[j][i+j-1]=max(d[j][i+j-1],d[j][k]+d[k+1][j+i-1]); 36 } 37 printf("%d\n",d[0][len-1]); 38 } 39 return 0; 40 }