括号序列(区间dp)
括号序列(区间dp)
输入一个长度不超过100的,由"(",")","[",")"组成的序列,请添加尽量少的括号,得到一个规则的括号序列。如有多解,输出任意一个序列即可。
括号序列是这样定义而成的:
- 空序列是括号序列
- 如果S是括号序列,那么(S)和[S]也是正规括号序列
- 如果A和B都是正规括号序列,那么AB也是正规括号序列。
所以,只要一个括号序列不是空序列,我们一定可以把它从两端剥开,或者把它划分成两个小括号序列。设\(f[i][j]\)表示字串\(s[i][j]\)至少要添加几个括号,那么\(f[i][j]\)一定可以转移到\(f[i][k]+f[k][j]\)。如果\(s[i]=s[j]\),那么也可以转移到\(f[i+1][j-1]\)。
由此可见,区间dp的必要条件是划分后解会不同。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=105;
int T, f[maxn][maxn], n;
char s[maxn];
//函数能使语义更清晰
bool match(int x, int y){ return s[y]-s[x]>0&&s[y]-s[x]<=2; }
void print(int l, int r){ //[l,r]
if (l>r) return;
if (l==r){
if (s[l]=='('||s[l]==')') printf("()");
else printf("[]"); return; }
int ans=f[l][r];
if (match(l, r)&&f[l+1][r-1]==ans){
putchar(s[l]); print(l+1, r-1); putchar(s[r]);
return; }
for (int k=l; k<r; ++k)
if (f[l][k]+f[k+1][r]==ans){
print(l, k); print(k+1, r); return; }
}
int main(){
scanf("%d", &T);
while (T--){
fgets(s, maxn, stdin);
fgets(s, maxn, stdin);
n=strlen(s)-1;
for (int i=0; i<n; ++i) f[i+1][i]=0, f[i][i]=1;
for (int i=n-2; i>=0; --i)
for (int j=i+1; j<n; ++j){
f[i][j]=n;
if (match(i, j)) f[i][j]=f[i+1][j-1]; //[i,j]
for (int k=i; k<j; ++k)
f[i][j]=min(f[i][j], f[i][k]+f[k+1][j]);
}
print(0, n-1); puts("");
}
return 0; //忘记return 0了!!
}
括号序列(区间dp)的更多相关文章
- TZOJ 3295 括号序列(区间DP)
描述 给定一串字符串,只由 “[”.“]” .“(”.“)”四个字符构成.现在让你尽量少的添加括号,得到一个规则的序列. 例如:“()”.“[]”.“(())”.“([])”.“()[]”.“()[( ...
- 括号序列的dp问题模型
括号序列的dp问题模型 Codeforces314E ◦给定一个长度为n的仅包含左括号和问号的字符串,将问号变成左括号或 右括号使得该括号序列合法,求方案总数. ◦例如(())与()()都是合法的括号 ...
- P1291-添加括号(区间dp)
题目背景 给定一个正整数序列a(1),a(2),...,a(n),(1<=n<=20) 不改变序列中每个元素在序列中的位置,把它们相加,并用括号记每次加法所得的和,称为中间和. 例如: 给 ...
- poj2955括号匹配 区间DP
Brackets Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 5424 Accepted: 2909 Descript ...
- poj 2955 括号匹配 区间dp
Brackets Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6033 Accepted: 3220 Descript ...
- 合法括号序列(dp+组合数学)
键盘上有左括号(,右括号),和退格键-,共三个键. 牛牛希望按键n次,使得输入的字符串恰好一个合法的括号序列. 每按一次左括号(,字符串末尾追加一个左括号( 每按一次右括号),字符串末尾追加一个右括号 ...
- 编程之美2015资格赛 题目2 : 回文字符序列 [ 区间dp ]
传送门 题目2 : 回文字符序列 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 给定字符串,求它的回文子序列个数.回文子序列反转字符顺序后仍然与原序列相同.例如字符串ab ...
- poj 2955 Brackets 括号匹配 区间dp
题意:最多有多少括号匹配 思路:区间dp,模板dp,区间合并. 对于a[j]来说: 刚開始的时候,转移方程为dp[i][j]=max(dp[i][j-1],dp[i][k-1]+dp[k][j-1]+ ...
- 九度OJ 1337:寻找最长合法括号序列 (DP)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:839 解决:179 题目描述: 给你一个长度为N的,由'('和')'组成的括号序列,你能找出这个序列中最长的合法括号子序列么?合法括号序列的 ...
- 51Nod 1522 上下序列 —— 区间DP
题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1522 区间DP,从大往小加: 新加入一种数有3种加法:全加左边,全 ...
随机推荐
- 图像处理检测方法 — ORB(Oriented FAST and Rotated BRIEF)
1.FAST FAST算子的基本原理是:若某像素点与其周围领域内足够多的连续的像素点存在某一属性差异,并且该差异大于指定阈值,则可以断定该像素点与其邻域像素有可被识别的不同之处,可以作为一个特征点( ...
- IDEA 加载Eclipse项目
- 实现html表头固定,表格内的信息向上滚动
效果如下: <!doctype html>Table header header two fuck 1 fuck 2 fuck 1 fuck 2 fuck 1 fuck 2 fuck 1 ...
- C 字节对齐.我的算法学习之路
C/C++基础笔试题1.0(字节对齐) http://blog.csdn.net/dengyaolongacmblog/article/details/37559687 我的算法学习之路 http:/ ...
- Struts2与OGNL
Action会自动放入值栈,成员变量会自动放入root区 如果是方法中的对象 要放入值栈 push()或者getRoot().push(); 界面取值 直接用对象的属性名进行取值
- T62
Forgiveness is the fragrance that the violet sheds on the heel that has crushed it.你一脚踩在紫罗兰上,它却把香味留在 ...
- BEC listen and translation exercise 36
你所持的护照可使你享有免费医疗.Your passport qualifies you to receive free medical treatment.公司指使其职员挖对手的客户.The comp ...
- Linux-解决putty无法直接使用root用户远程登录linux主机的问题
问题描述: 有时,在使用putty连接远程linux主机时会发现,无法直接使用root登录, 但是可以使用其他用户登录,然后切换至root用户. 解决办法: 1.修改配置文件 vi /etc/ssh/ ...
- Cannot find PHPUnit in include path (.;C:\php5\pear)
--pear channel-discover pear.phpunit.de --pear install phpunit/PHPUnit 此时会显示: No valid packages foun ...
- 汇编题目:按A键,当松开的时显示字母A
安装一个新的int9中断例程,功能:在DOS下,按下“A”键后,除非不再松开,如果松开,就显示满屏的“A”:其他的按键照常处理.提示:按下一个键时产生的扫描码称为通码,松开一个键时产生的扫描码称为断码 ...