J - 括号匹配
Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u
Submit Status

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 i1i2, …, im where 1 ≤ i1 < i2 < … < im ≤ nai1ai2 … 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 }
View Code