当前位置: 代码迷 >> 综合 >> POJ 2955 Brackets(区间dp)【括号弧模板】
  详细解决方案

POJ 2955 Brackets(区间dp)【括号弧模板】

热度:33   发布时间:2023-12-23 00:21:59.0

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,设dp[i][j]为从第i到第 j 个括号的最长匹配长度,这题题简单,但是要特别注意初始化,比较坑,

 首先初始化区间dp[i][i]为0,这很简单,然后要初始化dp[i][i+1],这里要判断,如果s[i]和s[i+1]是配对的,那么dp[i][i+1]就等于2了,否则就是0;

 接下来,比如说有长度为6的序列,假如求dp[2][5],那区间2到5的最大长度就是区间2~3加上4~5,区间2~4加上5和区间2~5  三者中的最大值,就是2~5的最大值,当然,

这里要提前判断一下2和5是不是配对的,如果配对的话,那就是区间3~4的值加上2,否则就是上面的遍历过程,这只是一个区间,其他区间都是如此,所以转移方程就是:

如果i,j不配对:

     dp[i][j]=max(dp[i][j], dp[i][k]+dp[k+1][j]);

如果配对:

     dp[i][j]=dp[i+1][j-1]+2;

 因为初始化问题哇了好几发呢,,要千万注意!!

 

【AC代码】

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=200;
int dp[N][N];
int m,n;
char s[N];int judge(char a,char b)
{if(a=='['&&b==']') return 1;if(a=='('&&b==')') return 1;return 0;
}int main()
{while(~scanf("%s",s)&&s[0]!='e'){int len=strlen(s);for(int i=0;i<len;++i)//预处理{dp[i][i]=0;if(judge(s[i],s[i+1]))dp[i][i+1]=2;elsedp[i][i+1]=0;}for(int i=3;i<=len;++i){for(int j=0;j+i-1<len;++j){int k=i+j-1;dp[j][k]=0;if(judge(s[j],s[k]))//配对的话dp[j][k]=dp[j+1][k-1]+2;for(int l=j;l<k;++l)//不配对的话{dp[j][k]=max(dp[j][k],dp[j][l]+dp[l+1][k]);}}}printf("%d\n",dp[0][len-1]);}return 0;
}


  相关解决方案