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…ana1,a2…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,…,imi1,i2,…,im where 1≤i1<i2<…<im≤n1≤i1<i2<…<im≤n, ai1,ai2…aimai1,ai2…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
题意:
给出一个括号序列,问最长合法非连续括号序列的长度。合法括号序列定义如下:
- 空串
- 如果s是合法的,那么(s)和[s]也是合法的
- 如果a,b是合法的,那么ab也是合法的
分析:
定义状态:dp[i][j]dp[i][j] 第ii个字符到第个字符的最长合法括号对的个数
对于当前状态有以下转移:
- 由于si+1,...,sjsi+1,...,sj 以及 si,...,sj−1si,...,sj−1 都是 si,...,sjsi,...,sj 的子串,故必有dp[i][j]=max(dp[i+1][j],dp[i][j−1])dp[i][j]=max(dp[i+1][j],dp[i][j−1])
- 如果 s[i]s[i] 和 s[j]s[j] 匹配,则有 dp[i][j]=max(dp[i][j],dp[i+1][j−1]+1)dp[i][j]=max(dp[i][j],dp[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])dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j])
由于题目所求为合法括号序列长度,而dp数组记录的是匹配的括号对数量,故,最终答案为 dp[0][strlen(s)−1]∗2dp[0][strlen(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;
}