题目链接: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. Non-Local Image Dehazing 复现

    本文选自CVPR 2016, 文章链接Dana Berman, Tali Treibitz, Shai Avidan. Non-Local Image Dehazing 复现源码见我的Github 无 ...

  2. CH3101 阶乘分解

    题目链接 分解\(n!\)的质因数,输出相应的\(p_i\)和\(c_i\). 其中\(1\leq n\leq 10^6\).   考虑每一个质因子 \(p\) 在 \(n!\) 中出现的次数.显然, ...

  3. shell 变量定义使用

    shell 中变量的几种类型: 1.局部变量:只在当前 shell 可用的变量, 2.环境变量:当前 shell 的子进程也可用的变量 3.shell 变量:一些由 shell 设置的特殊变量,如:$ ...

  4. 并发库应用之三 & 线程池与定时器应用

    在TCP服务器编程模型的原理,每一个客户端连接用一个单独的线程为之服务,当与客户端的会话结束时,线程也就结束了,即每来一个客户端连接,服务器端就要创建一个新线程.如果访问服务器的客户端很多,那么服务器 ...

  5. Hadoop生态圈-Hive的自定义函数之UDAF(User-Defined Aggregation Function)

    Hadoop生态圈-Hive的自定义函数之UDAF(User-Defined Aggregation Function) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.

  6. getContentLength() 指为 -1 的解决办法

    在这个坑里3个多小时啊.这里不得不抱怨下,国内的资料坑爹,全部copy不说,还是错的. 解决办法: 在服务端加入代码: File file = new File(path); //path为要下载的文 ...

  7. plsql developer导入数据库

    需要指向导入命令

  8. html向js传递id

    html获取id方法: <div id="thediv1" style="display:block" onclick="ceshi(this. ...

  9. input新类型详解

    http://www.webhek.com/post/html5-input-type.html

  10. POJ 1185 炮兵阵地 (状态压缩DP)

    题目链接 Description 司令部的将军们打算在NM的网格地图上部署他们的炮兵部队.一个NM的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用& ...