POJ2955 Brackets 题解 区间DP

题目链接:http://poj.org/problem?id=2955
【题目描述】
《规则的括号序列》
我们定义一个字符串序列为“规则的括号序列”当且仅当它满足如下条件:
1、空字符串是规则的括号序列;
2、如果字符串 s 是一个规则的括号序列,那么 (s) 和 [s] 也是规则的括号序列;
3、如果字符串 a 和 b 都是规则的括号序列,那么 ab 也是规则的括号序列;
4、除此之外的字符串都不能称为规则的括号序列。
举个例子,下面的这些字符串都是规则的括号序列:
(), [], (()), ()[], ()[()]
与此同时,下面的这些字符串都不是规则的括号序列:
(, ], )(, ([)], ([(]
给你一个字符串 a1a2...an,你的任务是找到它的最长的一个满足“规则的括号序列”条件的子序列,并输出该最长规则括号子序列的长度。也就是说,你需要找到最长的一组下表i1,i2,...,im,他们满足1≤i1<i2<...<im≤n,同时ai1aid...aim是规则的括号序列。
比如,给你一个字符串 ([([]])] ,它的最长规则的括号子序列是 [([])]。
【输入格式】
输入包含多组样例。每组样例占据一行,包含一个字符串,该字符串仅由 (,),[,]组成。字符串的长度在1到100之间。
输入数据的最后一行包含一个字符串“end”用于标识文件结束。
【输出格式】
对于每一组数据(除了最后的“end”),你需要输出它的最长规则的括号子序列的长度。
【样例输入】
((()))
()()()
([]])
)[)(
([][][)
end
【样例输出】
6
6
4
0
6
【题目分析】
涉及的知识点:区间动态规划(区间DP)。
为了方便起见,我们这里将“最长规则的括号序列”简称为“目标序列”。
我们用 dp[L][R] 表示 字符串 s 的子串 s[L..R] ,那么:
· 首先我们要确定,如果字符串 s 是空串,或者它的长度为1,那么它的目标序列的长度肯定是 0 ;
· 如果字符串 s 的长度为2, 那么当 s=="()" 或者 s=="[]" 的时候,它的目标序列的长度就是它本身的长度——2;否则,它的目标序列的长度为0。
· 当 s[L]==‘(‘ 并且 s[R]==‘)‘ 或者 s[L]==‘[‘ 并且 s[R]==‘]‘ 的时候, dp[L][R] 的一种备选方案(称为第1中备选方案)是 dp[L+1][R-1] + 2;
· 不过 (s‘) 或者 [s‘] (这里 s‘ 用于表示 s[L+1 .. R-1] 的目标序列)条件不一定是成立的,所以任何条件下都成立的一种备选方案(称为第2种备选方案)是 max(dp[L+1][R], dp[L][R-1]) ,即我们剔除掉最左边的字符串,或者最右边的字符串所能够带来的效果;
· 还有一种情况是字符串 s[L..R] 是两个字符串拼接而成的,那么这种情况下,它的一种备选方案(称为第3种备选方案)是 max(dp[L][i] + dp[i+1][R]) ,其中 L+1≤i<R-1。
然后我们发现还可以合并第2种备选方案到第3中备选方案中,因为 max(dp[L+1][R], dp[L][R-1]) 其实就等于 max(dp[L][i] + dp[i+1][R]) ,其中 i=L或R-1。
所以第2及第3中备选方案合并到一起就是 max(dp[L][i] + dp[i+1][R]) ,其中 L≤i<R。
据此,我们可以编写代码如下:

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
const int maxn = 101;
int n, dp[maxn][maxn];
string s;

int main() {
    while ((cin >> s) && s != "end") {
        fill(dp[0], dp[0]+maxn*maxn, 0);
        n = s.length();
        for (int l = 2; l <= n; l ++) {
            for (int i = 0; i+l-1 < n; i ++) {
                int j = i + l - 1;
                if (s[i] == ‘(‘ && s[j] == ‘)‘ || s[i] == ‘[‘ && s[j] == ‘]‘)
                    dp[i][j] = (l > 2 ? dp[i+1][j-1] : 0) + 2;
                for (int k = i; k < j; k ++)
                    dp[i][j] = max(dp[i][j], dp[i][k] + dp[k+1][j]);
            }
        }
        cout << dp[0][n-1] << endl;
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/mooncode/p/POJ2955.html

时间: 2024-08-11 05:05:05

POJ2955 Brackets 题解 区间DP的相关文章

poj2955 Brackets 简单区间dp

// poj2955 简单区间dp // d[i][j]表示i到j区间所能形成的最大匹配序列 // dp[i][j] = max(dp[i][k]+dp[k+1][j]){i<k<j} // dp[i][j] = max(dp[i+1][j-1]+2) if (s[i] match s[j]) // // 记忆化搜索的时候,将dp[i][i] = 0 ,其他赋值成-1; // // 做题的时候刚开始将dp[i][j]弄成0了,结果一直tle // 最后发现有好多的状态重复计算了,所以会tle

POJ2955 Brackets(区间DP)

给一个括号序列,求有几个括号是匹配的. dp[i][j]表示序列[i,j]的匹配数 dp[i][j]=dp[i+1][j-1]+2(括号i和括号j匹配) dp[i][j]=max(dp[i][k]+dp[k+1][j])(i<=k<j) 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 char str[111]; 6 int d[111

POJ 1141 Brackets Sequence (区间dp 记录路径)

题目大意: 给出一种不合法的括号序列,要求构造出一种合法的序列,使得填充的括号最少. 思路分析: 如果只要求输出最少的匹配括号的数量,那么就是简单的区间dp dp[i][j]表示 i - j 之间已经合法了最少添加的括号数. 转移 就是 dp[i] [j] = min  (dp[i+1][j]+1 , dp[ i+ 1] [ k -1 ] + dp[k+1] [j] (i k 位置的括号匹配)) 其次我们要记录路径,你发现  如果 dp [i] [j] 是由 dp [i+1] [j] 转移过来的

ZOJ1463:Brackets Sequence(区间DP)

Let us define a regular brackets sequence in the following way: 1. Empty sequence is a regular sequence. 2. If S is a regular sequence, then (S) and [S] are both regular sequences. 3. If A and B are regular sequences, then AB is a regular sequence. F

Blocks题解(区间dp)

Blocks题解 区间dp 阅读体验...https://zybuluo.com/Junlier/note/1289712 很好的一道区间dp的题目(别问我怎么想到的) dp状态 其实这个题最难的地方是这道题目的状态怎么设 首先既然是区间dp,那肯定最先想到的状态是 $dp[i][j]$表示消掉区间$[i,j]$上所有的块的最大分数 突然发现这个状态会受区间外和$i$或$j$颜色相同的块的影响 并且转移也并不好转移=_= 所以我们考虑换一种状态... 既然说会受到外面的块的影响?那考虑一种方法来

Brackets (区间DP)

个人心得:今天就做了这些区间DP,这一题开始想用最长子序列那些套路的,后面发现不满足无后效性的问题,即(,)的配对 对结果有一定的影响,后面想着就用上一题的思想就慢慢的从小一步一步递增,后面想着越来越大时很多重复,应该要进行分割, 后面想想又不对,就去看题解了,没想到就是分割,还是动手能力太差,还有思维不够. 1 for(int j=0;j+i<ch.size();j++) 2 { 3 if(check(j,j+i)) 4 dp[j][j+i]=dp[j+1][j+i-1]+2; 5 for(i

poj 1141 Brackets Sequence (区间DP)

Brackets Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 25893   Accepted: 7295   Special Judge Description Let us define a regular brackets sequence in the following way: 1. Empty sequence is a regular sequence. 2. If S is a re

uva1626 poj 1141 Brackets Sequence 区间dp 打印路径

// poj 1141 Brackets Sequence // 也是在紫书上看的一题,uva就是多了一个t组数据. // 经典区间dp // dp(i,j)表示区间[i,j]内所需要增加的括号数目 // 则分为两种情况 // 一种是s[i]和s[j]是匹配的则 // dp[i][j] = min(dp[i][j],dp[i+1][j-1]) // 另外一种情况是不匹配 // dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j]){i<k<j}; // 但是无

Brackets(区间dp)

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