POJ 2955 Brackets (动规)

Brackets

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 2999   Accepted: 1536

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, …, 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

((()))
()()()
([]])
)[)(
([][][)
end

Sample Output

6
6
4
0
6

Source

Stanford Local 2004

?如果找到一对匹配的括号[xxx]oooo,就把区间分成两部分,一部分是xxx,一部分是oooo,然后以此递归直到区间长度为1或者为2

?dp[i][j]表示区间[i,j]之间的最长合法括号子序列长度

?dp[i][j] = min{dp[i+1][j],

dp[i+1][k-1]+dp[k+1][j]+1

(i<=k<=j&&i和k是一对匹配的括号)

}

代码:

#include <iostream>
#include <string.h>
#include <math.h>
#include <stdio.h>
using namespace std;
#define M 110
int dp[M][M];
char str[M];
int math(int x,int y)      //判断是否配对。
{
    return str[x]==‘(‘ && str[y]==‘)‘||
           str[x]==‘{‘ && str[y]==‘}‘||
           str[x]==‘[‘ && str[y]==‘]‘;
}
int DFS(int s,int e)
{
    int i,ret,t;
    if(e<s)                return 0;                //对各种特殊情况进行考虑。
    if(e==s)               return dp[s][e]=0;
    if(e-s==1)             return dp[s][e]=math(s,e);
    if(dp[s][e]!=-1)       return dp[s][e];        //如果这个状态已经计算过。
    ret=DFS(s+1,e);                                //姿势不对,还是看别人的,不懂。
    for(i=s+1;i<=e;i++)                            //找能配对的括号。
        if(math(s,i))
    {
        t=DFS(s+1,i-1)+DFS(i+1,e)+1;
        if(t>ret) ret=t;
    }
    return dp[s][e]=ret;
}
int main()
{
    int i,j,k,n;
    while(scanf("%s",str))
    {
        if(str[0]==‘e‘) break;
        n=strlen(str);
        memset(dp,-1,sizeof(dp));
        DFS(0,n-1);
        printf("%d\n",dp[0][n-1]*2);
    }
    return 0;
}

POJ 2955 Brackets (动规),布布扣,bubuko.com

时间: 2024-08-03 07:18:21

POJ 2955 Brackets (动规)的相关文章

POJ 2955 Brackets(计数问题吗呵呵)

我只能说这道题和上一道动态规划的问题真的是太像了,连方法也一模一样 确实,计数也需要存状态,计数也是需要动规的. 此时d[i][j]表示的状态是s[i~j]的序列中有多少 不规则 的括号. #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n; char s[105]; int d[105][105]; bool match(char ch1,char ch2)

POJ 1088 滑雪 (动规)

滑雪 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 75664 Accepted: 28044 Description Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Michael想知道载一个区域中最长底滑坡.区域由一个二维数组给出.数组的每个数字代表点的高度.下面是一个例子 1 2 3 4 5 16 17 18 1

poj 2955 Brackets dp简单题

//poj 2955 //sep9 #include <iostream> using namespace std; char s[128]; int dp[128][128]; int n; int rec(int l,int r) { if(dp[l][r]!=-1) return dp[l][r]; if(l==r) return dp[l][r]=0; if(l+1==r){ if(s[l]=='('&&s[r]==')') return dp[l][r]=2; if(

POJ 2955 Brackets (区间dp 括号匹配)

Brackets Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3951   Accepted: 2078 Description We give the following inductive definition of a "regular brackets" sequence: the empty sequence is a regular brackets sequence, if s is a reg

poj 2955 Brackets【区间DP】

题目链接:http://poj.org/problem?id=2955 题意:求回文子串的最大长度. 解法:枚举区间长度,更新答案. 代码: #include <stdio.h> #include <ctime> #include <math.h> #include <limits.h> #include <complex> #include <string> #include <functional> #include

POJ 2955 Brackets

Brackets Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6622   Accepted: 3558 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

POJ 2955 Brackets (区间dp入门)

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

POJ 2955 Brackets (区间DP)

题意:给定一个序列,问你最多有多少个合法的括号. 析:区间DP,dp[i][j] 表示在 第 i 到 第 j 区间内最多有多少个合法的括号. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include <cmath> #include <ios

poj(2955)——Brackets(区间dp)

题意: 现在我们定义一种R串,它必须满足以下条件: 1)当它的字串是空的时候时,那么它是R串. 2)当它是R串时,那么(s)或是[s]也是R串. 3)当a和b都是R串时,那么ab也是R串. 这里我没有完全领悟题目的意思,所以我发现递推不过去.其实它的实质就是括号匹配. 也就是说这里的合法序列是指括号能够两两匹配的. if((a[s]=='('&&a[e]==')')||(a[s]=='['&&a[e]==']')) 这里的这种情况时当外围是相互匹配的时候. dp[s][e]