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 a1,a2…an a 1 , a 2 … a n , 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 i 1 , i 2 , … , i m where 1≤i1<i2<…<im≤n 1 ≤ i 1 < i 2 < … < i m ≤ n , ai1,ai2…aim a i 1 , a i 2 … a i m 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
题意:
给出一个括号序列,问最长合法非连续括号序列的长度。合法括号序列定义如下:
- 空串
- 如果s是合法的,那么(s)和[s]也是合法的
- 如果a,b是合法的,那么ab也是合法的
分析:
定义状态:
dp[i][j]
d
p
[
i
]
[
j
]
第
i
i
个字符到第个字符的最长合法括号对的个数
对于当前状态有以下转移:
- 由于
si+1,...,sj
s
i
+
1
,
.
.
.
,
s
j
以及
si,...,sj−1
s
i
,
.
.
.
,
s
j
−
1
都是
si,...,sj
s
i
,
.
.
.
,
s
j
的子串,故必有
dp[i][j]=max(dp[i+1][j],dp[i][j−1]) d p [ i ] [ j ] = m a x ( d p [ i + 1 ] [ j ] , d p [ i ] [ j − 1 ] )
- 如果
s[i]
s
[
i
]
和
s[j]
s
[
j
]
匹配,则有
dp[i][j]=max(dp[i][j],dp[i+1][j−1]+1) d p [ i ] [ j ] = m a x ( d p [ i ] [ j ] , d p [ i + 1 ] [ j − 1 ] + 1 )
- 区间
[i,j]
[
i
,
j
]
可以由区间
[i,k]
[
i
,
k
]
与区间
[k+1,j]
[
k
+
1
,
j
]
合并得到,即
dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]) d p [ i ] [ j ] = m a x ( d p [ i ] [ j ] , d p [ i ] [ k ] + d p [ k + 1 ] [ j ] )
由于题目所求为合法括号序列长度,而dp数组记录的是匹配的括号对数量,故,最终答案为 dp[0][strlen(s)−1]∗2 d p [ 0 ] [ s t r l e n ( s ) − 1 ] ∗ 2
代码:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<stdlib.h>
#include<iostream>
using namespace std;
#define bll long long
const int maxn = 110;
char s[maxn];
int dp[maxn][maxn];
bool check(int i,int j)
{
if (s[i] == '(' && s[j] == ')') return true;
if (s[i] == '[' && s[j] == ']') return true;
return false;
}
int main()
{
while (scanf("%s",s)!=EOF)
{
if (s[0] == 'e') break;
int len = strlen(s);
memset(dp,0,sizeof(dp));
for (int l = 1; l < len; l++)
{
for (int i = 0; i < len-l; i++)
{
int j = i+l;
dp[i][j] = max(dp[i+1][j],dp[i][j-1]);
/**[a] || (b)**/
if (check(i,j))
dp[i][j] = max(dp[i][j],dp[i+1][j-1]+1);
/**ab**/
for (int k = i+1; k < j; k++)
dp[i][j] = max(dp[i][j],dp[i][k]+dp[k+1][j]);
}
}
printf("%d\n",dp[0][len-1]<<1);
}
return 0;
}