题目链接: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(括号匹配二)的更多相关文章

  1. poj 1141 Brackets Sequence 区间dp,分块记录

    Brackets Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 35049   Accepted: 101 ...

  2. 区间DP POJ 1141 Brackets Sequence

    Brackets Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 29520   Accepted: 840 ...

  3. POJ 1141 Brackets Sequence

    Brackets Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 29502   Accepted: 840 ...

  4. CSUOJ 1271 Brackets Sequence 括号匹配

    Description ]. Output For each test case, print how many places there are, into which you insert a ' ...

  5. POJ 1141 Brackets Sequence (区间DP)

    Description Let us define a regular brackets sequence in the following way: 1. Empty sequence is a r ...

  6. POJ 1141 Brackets Sequence(区间DP, DP打印路径)

    Description We give the following inductive definition of a “regular brackets” sequence: the empty s ...

  7. poj 1141 Brackets Sequence (区间dp)

    题目链接:http://poj.org/problem?id=1141 题解:求已知子串最短的括号完备的全序列 代码: #include<iostream> #include<cst ...

  8. poj 1141 Brackets Sequence(区间DP)

    题目:http://poj.org/problem?id=1141 转载:http://blog.csdn.net/lijiecsu/article/details/7589877 定义合法的括号序列 ...

  9. POJ 2955 Brackets --最大括号匹配,区间DP经典题

    题意:给一段左右小.中括号串,求出这一串中最多有多少匹配的括号. 解法:此问题具有最优子结构,dp[i][j]表示i~j中最多匹配的括号,显然如果i,j是匹配的,那么dp[i][j] = dp[i+1 ...

随机推荐

  1. [POI2018]Powódź

    Description 在地面上有一个水箱,它的俯视图被划分成了n行m列个方格,相邻两个方格之间有一堵厚度可以忽略不计的墙,水 箱与外界之间有一堵高度无穷大的墙,因此水不可能漏到外面.已知水箱内每个格 ...

  2. web服务器nginx和apache的对比分析

         今天准备较详细的对比一下apache httpd与nginx两个web服务器的异同点.优缺点.由于我并不是做web开发的,所以有什么理解错误还请指出,想要了解它们是因为工作中有时候会用到它, ...

  3. Netflix的zuul使用

    1.zuul出现的原因 2.zuul的介绍 3.zuul如何使用 4.zuul的一些注意事项

  4. spring cloud-zuul的Filter详解(十一)

    本文转自:http://blog.csdn.net/liuchuanhong1/article/details/62236793 关于网关的作用,这里就不再次赘述了,我们今天的重点是zuul的Filt ...

  5. Python【pymysql】模块

    import pymysql# 1.连上数据库 账号.密码 ip 端口号 数据库#2.建立游标#3.执行sql#4 .获取结果# 5.关闭游标#6.连接关闭coon = pymysql.connect ...

  6. Hadoop生态圈-hbase常用命令

    Hadoop生态圈-hbase常用命令 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.

  7. 微信图片上传,遇到一个神奇的jgp

    微信图片上传,获取图片base64遇到一个神奇的   jgp var imgFn = function (event) { event.preventDefault(); var id = '#'+$ ...

  8. PHP数组的遍历

    对于012345...这样的数组可以用for进行遍历 $arr=array('a','b','c','d','e'); for($key=0;$key<count($arr);$key++){ ...

  9. LintCode 204: Singleton

    LintCode 204: Singleton 题目描述 单例是最为最常见的设计模式之一.对于任何时刻,如果某个类只存在且最多存在一个具体的实例,那么我们称这种设计模式为单例.例如,对于class M ...

  10. 《C语言程序设计基础I》秋季学习总结

    希望下学期比这学期轻松,学习能力上升,只是越发丰富. 一步一步的走踏实了