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. Ubutu安装oracle jdk1.8

    环境: Ubuntu 18.04 LTS x64位 系统用户  hou 工具: jdk-8u171-linux-x64.tar.gz 实验的心 步骤: 第一步: 查看有没有装jdk,按住  ctr+a ...

  2. print不是函数

    对文章阅读有感!!! 文章地址:http://www.laruence.com/2019/03/01/4904.html print是一个语法结构(language constructs), 他并不是 ...

  3. 使用Image Sharp 对二维码图片中间加入logo图片

    1.在NuGet包源加入Image Sharp包源 2.在需要用到Image Sharp的项目中安装以下的插件 3.调用图片上绘制图片的方法

  4. ROS2GO 与WIN10 双系统安装

    关于ROS2GO的一些心得: 我是一个ROS的探索者,在接触ROS一段时间后,意外发现了一个关于ROS2GO的信息,是天之博特的微信公众号发表的.简单来说ROS2GO就是一个装了ROS的Ubuntu系 ...

  5. python+selenium自动化禅道登录测试

    本文以禅道登录测试为例,思路主要分openBrowser.openUrl.findElement.sendVals.checkResult.ReadUserdate六部分 openBrowser de ...

  6. FormData控制台打印为空及使用方法

    之前使用formData都是在network中查看参数,最近在做一个项目,接口还没有,用的假数据做的交互,突发奇想的console.log了 一下,结果是空的. 一开始以为append失效了,经过查证 ...

  7. rest_framework:响应器(渲染器)

    一.作用: 根据用户的请求url或者用户可接受的类型.筛选出合适的渲染组件 用户请求url: http://127.0.0.1:8000/test/?format=json http://127.0. ...

  8. 2019-08-07 纪中NOIP模拟B组

    T1 [JZOJ1385] 直角三角形 题目描述 二维平面坐标系中有N个位置不同的点. 从N个点选择3个点,问有多少选法使得这3个点形成直角三角形. 数据范围 $3 \leq N \leq 1500$ ...

  9. date-fns时间库的基本使用

    在react中使用date-fns: import sub_days from 'date-fns/sub_days'; import start_of_week from 'date-fns/sta ...

  10. Gin_入门

    1. 创建路由 1.1 Restful风格的API gin支持Restful风格的API 即Representational State Transfer的缩写.直接翻译的意思是"表现层状态 ...