POJ 1141 Brackets Sequence(括号匹配二)
题目链接:http://poj.org/problem?id=1141
题目大意:给你一串字符串,让你补全括号,要求补得括号最少,并输出补全后的结果。
解题思路:
开始想的是利用相邻子区间,即dp[i+1][j]之类的方法求,像是求回文串的区间DP一样。然后花了3个多小时,GG。。。
错误数据:
(())(]][[)
my:6 (()()()[][][][])
ans:4 (())([][][][])
括号匹配跟回文串不同,并不能通过dp[i+1][j]或者dp[i][j-1]推得dp[i][j],可能是因为回文串必须满足称性质。
而括号匹配可能可以划分成连个任意大小的子区间而没有影响。
然后正解跟括号匹配一差不多,因为你想啊,括号匹配一求的是最多的括号对数,把原字符串长度减一下最大括号匹配数,不就是最少需要补全的括号数了嘛,我竟然想了这么久。。。
设dp[i][j]为[i,j]最少需要补齐的括号数,得到状态转移方程:
if(str[i]=='('&&str[j]==')'||str[i]=='['&&str[j]==']'){
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)
然后,如果dp[i][j]由dp[i][k]和dp[i][k+1]组成,则记录path[i][j]=k,否则记为-1,最后递归输出一下就行了。
注意:输入用while(~scanf("%s",s))会错,不知道为什么
代码
#include<cstdio>
#include<cmath>
#include<cctype>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<string>
#define lc(a) (a<<1)
#define rc(a) (a<<1|1)
#define MID(a,b) ((a+b)>>1)
#define fin(name) freopen(name,"r",stdin)
#define fout(name) freopen(name,"w",stdout)
#define clr(arr,val) memset(arr,val,sizeof(arr))
#define _for(i,start,end) for(int i=start;i<=end;i++)
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
typedef long long LL;
const int N=1e3+;
const int INF=0x3f3f3f3f;
const double eps=1e-; int dp[N][N],path[N][N];
char str[N]; void print(int l,int r){
if(l>=r){
if(l==r){
if(str[l]==')'||str[l]=='(')
printf("()");
if(str[l]==']'||str[l]=='[')
printf("[]");
}
return;
}
if(path[l][r]==-){
printf("%c",str[l]);
print(l+,r-);
printf("%c",str[r]);
}
else{
int k=path[l][r];
print(l,k);
print(k+,r);
}
} int main(){
while(gets(str)){
memset(path,-,sizeof(path));
int n=strlen(str);
for(int i=;i<=n;i++){
dp[i][i]=;
}
for(int len=;len<n;len++){
for(int i=;i+len<n;i++){
int j=i+len;
dp[i][j]=INF;
if(str[i]=='('&&str[j]==')'||str[i]=='['&&str[j]==']'){
dp[i][j]=dp[i+][j-];
}
for(int k=i;k<j;k++){
if(dp[i][j]>dp[i][k]+dp[k+][j]){
dp[i][j]=dp[i][k]+dp[k+][j];
path[i][j]=k;
}
}
}
}
print(,n-);
printf("\n");
}
return ;
}
附上写错的代码做个纪念,毕竟写了这么久也是有感情的。。。
#include<cstdio>
#include<cmath>
#include<cctype>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<string>
#define lc(a) (a<<1)
#define rc(a) (a<<1|1)
#define MID(a,b) ((a+b)>>1)
#define fin(name) freopen(name,"r",stdin)
#define fout(name) freopen(name,"w",stdout)
#define clr(arr,val) memset(arr,val,sizeof(arr))
#define _for(i,start,end) for(int i=start;i<=end;i++)
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
typedef long long LL;
const int N=1e3+;
const int INF=0x3f3f3f3f;
const double eps=1e-; int dp[N][N],path[N][N];
char str[N];
int flag[N];
void print(int x,int y){ if(x>=y){
if(x==y)
flag[x]=;
return;
}
int t=path[x][y];
if(t==){
flag[x]=;
print(x+,y);
}
if(t==){
flag[y]=;
print(x,y-);
}
if(t==){
print(x+,y-);
}
if(t==){
print(x+,y);
}
if(t==){
print(x,y-);
}
}
//[)[)]]
int main(){
while(gets(str)){
int n=strlen(str);
memset(dp,,sizeof(dp));
memset(path,-,sizeof(path));
memset(flag,,sizeof(flag));
for(int i=;i<=n;i++){
dp[i][i]=;
}
for(int len=;len<n;len++){
for(int i=;i+len<n;i++){
int j=i+len;
dp[i][j]=INF;
int t1=dp[i+][j]+,t2=dp[i][j-]+,t3=dp[i+][j-],t4=dp[i+][j],t5=dp[i][j-];
dp[i][j]=min(dp[i][j],t1);
dp[i][j]=min(dp[i][j],t2);
if(min(t1,t2)==t1)
path[i][j]=;
else
path[i][j]=;
if(str[i]=='('&&str[j]==')'||str[i]=='['&&str[j]==']'&&t3<dp[i][j]){
dp[i][j]=t3;
path[i][j]=;
}
if(str[i]=='('&&str[i+]==')'||str[i]=='['&&str[i+]==']'&&t4<dp[i][j]){
dp[i][j]=t4;
path[i][j]=;
}
if(str[j]==')'&&str[j-]=='('||str[j]==']'&&str[j-]=='['&&t5<dp[i][j]){
dp[i][j]=t5;
path[i][j]=;
}
if(len==)
cout<<"i="<<i<<" j="<<j<<" "<<dp[i][j]<<" "<<path[i][j]<<endl;
}
}
//printf("%d\n",dp[0][n-1]);
print(,n-);
for(int i=;i<n;i++){
if(flag[i]){
if(str[i]=='(')
cout<<"()";
if(str[i]==')')
cout<<"()";
if(str[i]=='[')
cout<<"[]";
if(str[i]==']')
cout<<"[]";
}
else
cout<<str[i];
}
printf("\n");
}
return ;
}
POJ 1141 Brackets Sequence(括号匹配二)的更多相关文章
- poj 1141 Brackets Sequence 区间dp,分块记录
Brackets Sequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 35049 Accepted: 101 ...
- 区间DP POJ 1141 Brackets Sequence
Brackets Sequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 29520 Accepted: 840 ...
- POJ 1141 Brackets Sequence
Brackets Sequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 29502 Accepted: 840 ...
- CSUOJ 1271 Brackets Sequence 括号匹配
Description ]. Output For each test case, print how many places there are, into which you insert a ' ...
- POJ 1141 Brackets Sequence (区间DP)
Description Let us define a regular brackets sequence in the following way: 1. Empty sequence is a r ...
- POJ 1141 Brackets Sequence(区间DP, DP打印路径)
Description We give the following inductive definition of a “regular brackets” sequence: the empty s ...
- poj 1141 Brackets Sequence (区间dp)
题目链接:http://poj.org/problem?id=1141 题解:求已知子串最短的括号完备的全序列 代码: #include<iostream> #include<cst ...
- poj 1141 Brackets Sequence(区间DP)
题目:http://poj.org/problem?id=1141 转载:http://blog.csdn.net/lijiecsu/article/details/7589877 定义合法的括号序列 ...
- POJ 2955 Brackets --最大括号匹配,区间DP经典题
题意:给一段左右小.中括号串,求出这一串中最多有多少匹配的括号. 解法:此问题具有最优子结构,dp[i][j]表示i~j中最多匹配的括号,显然如果i,j是匹配的,那么dp[i][j] = dp[i+1 ...
随机推荐
- Android学习笔记——关于onConfigurationChanged(转)
从事Android开发,免不了会在应用里嵌入一些广告SDK,在嵌入了众多SDK后,发现几乎每个要求在AndroidManifest.xml申明Activity的广告SDK都会要求加上注明这么一句属性: ...
- 「转」python数字图像处理(18):高级形态学处理
python数字图像处理(18):高级形态学处理 形态学处理,除了最基本的膨胀.腐蚀.开/闭运算.黑/白帽处理外,还有一些更高级的运用,如凸包,连通区域标记,删除小块区域等. 1.凸包 凸包是指一 ...
- cocoaPods安装、更新第三方库
pod install 换成 pod install --verbose --no-repo-update pod update 换成 pod update --verbose --no-repo-u ...
- mysql 中的共享锁和排他锁
共享锁(share lock) 共享锁又称读锁,是读取操作创建的锁.其他用户可以并发读取数据,但任何事务都不能对数据进行修改(获取数据上的排他锁),直到已释放所有共享锁. 如果事务T对数据A加上共享锁 ...
- C语言基础语法
#include <stdio.h> int main() { int age; printf("input your age"); scanf("%d&qu ...
- 用Anaconda安装本地python包
Anaconda确实带来了很多方便,但是之前也过多的依赖了conda自带的一键下载python包的功能.这不,这几天突然要用FastFM这个包,无奈conda里没有,于是只能从github下载下来,实 ...
- Tweepy1——抓取Twitter数据
sklearn实战-乳腺癌细胞数据挖掘 https://study.163.com/course/introduction.htm?courseId=1005269003&utm_campai ...
- Java基础-日期格式化DateFormat类简介
Java基础-日期格式化DateFormat类简介 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.DateFormat类概述 DateFormat 是日期/时间格式化子类的抽象 ...
- Linux 下搭建 Svn+Apache
一.安装apache 1.检查apache是否安装 rpm -qa|grep httpd 2.使用yum安装apache yum -y install httpd 3.记住安装的版本号 httpd.x ...
- bzoj千题计划144:bzoj1176: [Balkan2007]Mokia
http://www.lydsy.com/JudgeOnline/problem.php?id=1176 CDQ分治 #include<cstdio> #include<iostre ...