题目
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 | Output |
---|---|
((())) ()()() ([]]) )[)( ([][][) end | 6 6 4 0 6 |
题目大意 : 给你一个字符串,找最大能凑成对的括号序列
思路 : 区间dp
状态表示 f[i,j] 表示从i到j的区间里合法的成对的括号序列长度
属性 : 最大值
状态计算 :
1 . 当第i个 和第j个匹对时 ,让 f[i,j] = f[i+1,j-1] +2;
如果不匹对 f[i,j] = f[i+1,j-1]
2 ,但是不能保证上方操作就是最大值 ,在i,j 区间里,找怎么合并取最大最大值,
代码如下
#include<iostream>
#include<cstring>
using namespace std;
const int N=111;
int f[N][N];
struct node // 记录当前的符号
{
bool n1,n2,m1,m2;
}a[N];
string s;
int main()
{
while(cin>>s)
{
memset(a,0,sizeof a);
if(s=="end") break;
int n=s.size();
for(int i=0;i<n;i++)
{
if(s[i]=='[') a[i+1].m1=true;
if(s[i]==']') a[i+1].m2=true;
if(s[i]=='(') a[i+1].n1=true;
if(s[i]==')') a[i+1].n2=true;
}
memset(f,0,sizeof f); // 初始化
for(int len=2;len<=n;len++)
{
for(int l=1;l<=n-len+1;l++)
{
int r=len+l-1;
if((a[l].m1 && a[r].m2 )||( a[l].n1 && a[r].n2)) // 如果匹对成功
{
f[l][r]=f[l+1][r-1]+2;
}
else f[l][r]=f[l+1][r-1];
for(int k=l;k<r;k++) // 在区间中找最大值
{
f[l][r]=max(f[l][r],f[l][k]+f[k+1][r]);
}
}
}
cout<<f[1][n]<<endl;
}
return 0;
}