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 \(a_{1}a_{2} … a_{n}\), 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 \(i_{1}, i_{2}, …, i_{m}\) where \(1 ≤ i_{1} < i_{2} < … < i_{m} ≤ n, a_{i1}a_{i2} … a_{im}\) 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

Solution

题意简述:给出一个的只有'(',')','[',']'四种括号组成的字符串,求最多有多少个括号满足题目里所描述的完全匹配。

本题考察了区间DP,可以称为是区间DP的模板题。

区间DP的板子(来源:https://blog.csdn.net/qq_40772692/article/details/80183248):

for (int len = 1; len <= n; len++)//枚举长度
{
for (int j = 1; j + len <= n + 1; j++)//枚举起点,ends<=n
{
int ends = j + len - 1;
for (int i = j; i < ends; i++)//枚举分割点,更新小区间最优解
{
dp[j][ends] = min(dp[j][ends], dp[j][i] + dp[i + 1][ends] + something);
}
}
}

令\(dp[i][j]\)为区间\(i\)~\(j\)中最长合法序列的长度。

首先,可以直接判断输入的字符串的第\(i\)位和第\(j\)位是否匹配,如果能成功匹配,就更新\(dp[i][j] = dp[i + 1][j - 1] + 2\)。

在这个基础上,枚举分割点\(k\),更新小区间内的最优解。

为了方便存储,我们将字符串整体向右移动\(1\)位。

最后输出\(dp[1][字符串长度]\)即可。

Code

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cctype> using namespace std; inline int gi()
{
int f = 1, x = 0; char c = getchar();
while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar();}
while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar();}
return f * x;
} char s[103];
int dp[103][103]; int main()
{
while (scanf("%s", s + 1) != EOF)//将输入的字符串整体右移1位
{
memset(dp, 0, sizeof(dp));//dp数组清零
int len = strlen(s + 1);//字符串长度
if (s[1] == 'e') return 0;//输入结束
/*开始区间DP*/
for (int i = 1; i <= len; i++)//枚举长度
{
for (int j = 1; j + i <= len + 1; j++)//枚举起点
{
int k = j + i - 1;//终点
if ((s[j] == '(' && s[k] == ')') || (s[j] == '[' && s[k] == ']')) //如果s[i]和s[j]相匹配
{
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[1][len]);//输出答案,记得换行
}
return 0;//结束
}

题解【POJ2955】Brackets的更多相关文章

  1. POJ2955 Brackets —— 区间DP

    题目链接:https://vjudge.net/problem/POJ-2955 Brackets Time Limit: 1000MS   Memory Limit: 65536K Total Su ...

  2. POJ-2955 Brackets(括号匹配问题)

    题目链接:http://poj.org/problem?id=2955 这题要求求出一段括号序列的最大括号匹配数量 规则如下: the empty sequence is a regular brac ...

  3. poj2955:Brackets

    Brackets Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8716   Accepted: 4660 Descript ...

  4. poj2955 Brackets (区间dp)

    题目链接:http://poj.org/problem?id=2955 题意:给定字符串 求括号匹配最多时的子串长度. 区间dp,状态转移方程: dp[i][j]=max ( dp[i][j] , 2 ...

  5. 间隔DP基础 POJ2955——Brackets

    取血怒.first blood,第一区间DP,这样第一次没有以某种方式在不知不觉中下降~~~ 题目尽管是鸟语.但还是非常赤裸裸的告诉我们要求最大的括号匹配数.DP走起~ dp[i][j]表示区间[i, ...

  6. 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]+d ...

  7. POJ2955 Brackets (区间DP)

    很好的区间DP题. 需要注意第一种情况不管是否匹配,都要枚举k来更新答案,比如: "()()()":dp[0][5]=dp[1][4]+2=4,枚举k,k=1时,dp[0][1]+ ...

  8. 各种DP总结

    一.数位DP 1.含有或不含某个数“xx”: HDU3555 Bomb HDU2089 不要62 2.满足某些条件,如能整除某个数,或者数位上保持某种特性: HDU3652 B-number Code ...

  9. [总结-动态规划]经典DP状态设定和转移方程

    马上区域赛,发现DP太弱,赶紧复习补上. #普通DP CodeForces-546D Soldier and Number Game 筛法+动态规划 待补 UVALive-8078 Bracket S ...

随机推荐

  1. 避免layui form表单重复触发submit绑定事件

    个人博客 地址:http://www.wenhaofan.com/article/20180927002336 在使用以下代码监听lay-filter为editConfig的提交按钮后,当点击提交按钮 ...

  2. Java后端知识体系及路线【最新秘籍】

    第一层(基本语法)   第一层心法,主要都是基本语法,程序设计入门,悟性高者十天半月可成,差一点的 3 到 6 个月也说不准.如果有其他开发语言的功底相助,并且有张无忌的悟性与运气,相信第一层只在片刻 ...

  3. yolov3 讲解

    参考博客:https://blog.csdn.net/litt1e/article/details/88907542

  4. 10.3lambda表达式笔记

    与参数不同被捕获的变量的值是在lambda创建时拷贝,而不是调用时拷贝 void fcn() { int v1 = 42; //局部变量 auto f = [v1] { return v1; }; a ...

  5. Centsos7 aria2

    wget -N --no-check-certificate https://raw.githubusercontent.com/ToyoDAdoubi/doubi/master/aria2.sh & ...

  6. eclipse的安装和环境配置

    一,eclipse下载 地址:https://www.eclipse.org/downloads/ 一般浏览器都有翻译功能 二.有32位和64位的版本根据自己的需求下载,选下载的选下载量最多的下载. ...

  7. 【Python】获取星期字符串

    原理:字符串切片 1.0代码: #获取星期字符串 weekStr="星期一星期二星期三星期四星期五星期六星期日" weekId=eval(input("请输入星期数字(1 ...

  8. layer iframe 设置关闭按钮 和刷新和弹出框设置

    layer弹出层的关闭问题   就是在执行添加或修改的时候,需要将数据提交到后台进行处理,这时候添加成功之后最理想的状态是关闭弹出层并且刷新列表的数据信息,之前一直想实现这样,可一直没有成功,今天决定 ...

  9. 赋值SQL语句

    UPDATE TAB_DEV_MS SET DT_DETECTION_STARTTIME = TO_DATE ( '2017-01-01 00:00:00', 'YYYY-MM-DD HH24:MI: ...

  10. Windows10 远程桌面连接失败,报CredSSP加密oracle修正错误解决办法

    最近Windows10 升级后,发现不能远程连接. 不能访问的都报下面这个错了: 原因:按照提示的微软地址,看了下大致就是服务器端没有更新,而我的win10已经更新了一个安全补丁,如果双方都没有打补丁 ...