题目链接: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. 一、spark错误

    1. 17/07/17 15:34:55 ERROR yarn.ApplicationMaster: User class threw exception: java.lang.Unsupported ...

  2. 小技巧--tab键自动补齐Git命令

    Git是什么,你不清楚? 好吧,那么该篇内容对你也木有帮助,请绕道而行.. 我们在使用Git命令时,可以通过tab键,自动补齐Git,特别是在切换分支时特别有用. 如下,当我们想将当前分支切换到bug ...

  3. 【bzoj4826】影魔

    Portal --> bzoj4826 Solution 为什么莫名读了很长时间的题...== 逐渐不会语文qwq 貌似这题的做法很多,丢上来的话是因为..这个化简条件的过程莫名爽哈哈哈哈哈 注 ...

  4. Java7的新特性

    原文出处:xixicat 序 本文主要讲Java7的新特性,相对于Java6而言,Java7增加了一些重要的特性,比如NIO2,不像Java6那么鸡肋,也算是一个重要的版本. 特性列表 suppres ...

  5. SPI、I2C、UART、I2S、GPIO、SDIO、CAN

    总线,总线,总要陷进里面.这世界上的信号都一样,但是总线却成千上万,让人头疼. 总的来说,总线有三种:内部总线.系统总线和外部总线.内部总线是微机内部各外围芯片与处理器之间的总线,用于芯片一级的互连: ...

  6. windows下使用tftp工具下载文件到开发板(linux)

    1.下载tftp工具,也可以上CSDN找个免费0积分的 http://www.52z.com/soft/11886.html 2.确保开发板和windows在同一网段 比如192.168.101.*段 ...

  7. JAVA-JSP隐式对象

    JSP隐式对象 在本章中,我们将讨论和学习JSP中的隐式对象.这些对象是JSP容器为每个页面中的开发人员提供的Java对象,开发人员可以直接调用它们而不用显式地声明它们再调用. JSP隐式对象也称为预 ...

  8. hdu 3065病毒侵袭持续中

    病毒侵袭持续中 http://acm.hdu.edu.cn/showproblem.php?pid=3065 Time Limit: 2000/1000 MS (Java/Others)    Mem ...

  9. HDU 2176 基础NIM 输出方案

    普通的NIM,然后问先手必胜第一次操作后的所有局面. 对于一个必胜局面只要转变局面SG值为必败(SG=0)留给后手就行了. /** @Date : 2017-10-13 21:39:13 * @Fil ...

  10. SQL语句(十八)—— 存储过程

    存储过程 系统存储过程 自定义存储过程 扩展存储过程 一.创建存储过程 创建存储过程 --例1 USE SU GO Create Procedure SelProc AS Select * From ...