题解【POJ2955】Brackets
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
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的更多相关文章
- POJ2955 Brackets —— 区间DP
题目链接:https://vjudge.net/problem/POJ-2955 Brackets Time Limit: 1000MS Memory Limit: 65536K Total Su ...
- POJ-2955 Brackets(括号匹配问题)
题目链接:http://poj.org/problem?id=2955 这题要求求出一段括号序列的最大括号匹配数量 规则如下: the empty sequence is a regular brac ...
- poj2955:Brackets
Brackets Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 8716 Accepted: 4660 Descript ...
- poj2955 Brackets (区间dp)
题目链接:http://poj.org/problem?id=2955 题意:给定字符串 求括号匹配最多时的子串长度. 区间dp,状态转移方程: dp[i][j]=max ( dp[i][j] , 2 ...
- 间隔DP基础 POJ2955——Brackets
取血怒.first blood,第一区间DP,这样第一次没有以某种方式在不知不觉中下降~~~ 题目尽管是鸟语.但还是非常赤裸裸的告诉我们要求最大的括号匹配数.DP走起~ dp[i][j]表示区间[i, ...
- 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 ...
- POJ2955 Brackets (区间DP)
很好的区间DP题. 需要注意第一种情况不管是否匹配,都要枚举k来更新答案,比如: "()()()":dp[0][5]=dp[1][4]+2=4,枚举k,k=1时,dp[0][1]+ ...
- 各种DP总结
一.数位DP 1.含有或不含某个数“xx”: HDU3555 Bomb HDU2089 不要62 2.满足某些条件,如能整除某个数,或者数位上保持某种特性: HDU3652 B-number Code ...
- [总结-动态规划]经典DP状态设定和转移方程
马上区域赛,发现DP太弱,赶紧复习补上. #普通DP CodeForces-546D Soldier and Number Game 筛法+动态规划 待补 UVALive-8078 Bracket S ...
随机推荐
- meet in the middle 折半搜索 刷题记录
复杂度分析 假设本来是n层,本来复杂度是O(2^n),如果meet in middle那就是n/2层,那复杂度变为O( 2^(n/2) ),跟原来的复杂度相比就相当于开了个方 比如如果n=40那爆搜2 ...
- idea 添加 开发者信息
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end #parse( ...
- Nginx实现前端访问后端本地接口
Nginx配置两个地方就行: 先是配置好自己项目的服务,确保自己的项目能运行: location / { root /web/xiangmu/public; // 本地项目的路径 index inde ...
- numpy 中array 和ndrray的区别联系
numpy.array() 标明array只是一个方法 ndarray 是类名,是一个实例. a=numpy.array(b) #这是把变量b转换为数组a,这里array()是个方法,a的类型 ...
- springboot整合websocket实现客户端与服务端通信
定义 WebSocket是通过单个TCP连接提供全双工(双向通信)通信信道的计算机通信协议.此WebSocket API可在用户的浏览器和服务器之间进行双向通信.用户可以向服务器发送消息并接收事件驱 ...
- Codeforces Round #600 (Div. 2) C - Sweets Eating
#include<iostream> #include<algorithm> #include<cstring> using namespace std ; typ ...
- 题解【洛谷P2070】刷墙
题面 将每一次移动的距离进行差分,前缀和判断移动的距离是否\(\geq 2\)即可. #include <bits/stdc++.h> #define itn int #define gI ...
- OpenShift 4.3环境中创建基于Go的Operator
详细步骤可以参考官方文档 https://docs.openshift.com/container-platform/4.3/operators/operator_sdk/osdk-getting-s ...
- selenium获取短暂出现元素的xpath路径
1. pip install beautifulsoup4 :安装beautifulsoup4 2. from bs4 import BeautifulSoup 3. bs = BeautifulS ...
- jQuery func
1. $(selector).each(function(index,element)); -----------index 选择器的index位置,element --当前的元素 2. _.eac ...