您的位置:首页 > 其它

POJ 2955 Brackets(区间DP)

2013-11-26 22:25 357 查看
Brackets

Time Limit: 1000MSMemory Limit: 65536K
Total Submissions: 2302Accepted: 1178
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 i1, i2, …, imwhere 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
((()))
()()()
([]])
)[)(
([][][)
end

Sample Output
6
6
4
0
6

Source
Stanford Local 2004


/****************************************************
* author:crazy_石头
* Pro:POJ2955
* algorithm:区间DP-记忆化搜索
* Time:47ms
* Judge Status:Accepted
*******************************************************/
#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <vector>
#include <algorithm>

using namespace std;

#define rep(i,h,n) for(int i=(h);i<=(n);i++)
#define ms(a,b) memset((a),(b),sizeof(a))
#define eps 1e-6
#define INF 1<<29
#define LL __int64

const int maxn=100+20;

char str[maxn];
int dp[maxn][maxn];

inline bool ok(int l,int r)
{
    if((str[l]=='['&&str[r]==']')||(str[l]=='('&&str[r]==')'))
        return true;
    return false;
}
//dp[l][r]表示l到r之间匹配的括号对数;
//若第l个括号没有与其匹配的括号,则舍弃第l个位置,所以有dp[l][r]=dp[l+1][r];
//若能找到有匹配的括号,则把区间化小,在子区间计算,以k为断点;
//此时方程为:dp[l][r]=max(dp[l][r],dp[l][k-1]+dp[k][r]+2);
inline int dfs(int l,int r)
{
    if(~dp[l][r])return dp[l][r];
    if(r<=l)return dp[l][r]=0;

    else if(l+1==r)//区间长度为2时,若这两个括号匹配,返回2,否则返回长度为0;
    {
        if(ok(l,r))
            return dp[l][r]=2;
        else
            return dp[l][r]=0;
    }
    dp[l][r]=dfs(l+1,r);
    rep(k,l+1,r)
    {
        if(ok(l,k))
        dp[l][r]=max(dp[l][r],dfs(l+1,k-1)+dfs(k,r)+2);
    }
    return dp[l][r];
}

int main()
{
    while(scanf("%s",str)&&strcmp(str,"end")!=0)
    {
        ms(dp,-1);
        int len=strlen(str);
        printf("%d\n",dfs(0,len-1));
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: