题意

给出两个括号序列 \(S\) 和 \(T\),让你构造一个最短的合法括号序列使 \(S\) 和 \(T\) 是它的子序列。

分析

设 \(dp[i][j][k]\) 为这个最短的合法括号序列的前缀包含 \(S\) 的前 \(i\) 个字符,T的前 \(j\) 个字符且左括号的数量大于右括号的数量为 \(k\)时的长度。

  • 如果我们要添加一个左括号

    \(dp[nexi][nexj][k+1]=min(dp[i][j][k]+1,dp[nexi][nexj][k+1])\)

    \(nexi\) 为添加一个左括号后能匹配到的下一个 \(i\),\(nexj\) 为添加一个左括号能匹配到的下一个 \(j\)

  • 如果我们要添加一个右括号

    \(dp[nexi][nexj][k-1]=min(dp[i][j][k]+1,dp[nexi][nexj][k-1])\)

    \(nexi\) 为添加一个右括号后能匹配到的下一个 \(i\),\(nexj\) 为添加一个右括号能匹配到的下一个 \(j\)

\(dp\) 过程中用一个数组记录下转移的前驱就可以倒推还原这个括号序列。

Code

#include<bits/stdc++.h>
#define fi first
#define se second
#define lson l,mid,p<<1
#define rson mid+1,r,p<<1|1
#define pb push_back
#define ll long long
using namespace std;
const int inf=1e9;
const int mod=1e9+7;
const int maxn=2e2+10;
char s[maxn],t[maxn];
int n,m;
int dp[maxn][maxn][2*maxn];
struct ppo{
int x,y,k;
char c;
}pre[maxn][maxn][2*maxn];
int main(){
//ios::sync_with_stdio(false);
//freopen("in","r",stdin);
scanf("%s%s",s,t);
n=strlen(s);m=strlen(t);
for(int i=0;i<=n;i++) for(int j=0;j<=m;j++) for(int k=0;k<2*maxn;k++) dp[i][j][k]=inf;
dp[0][0][0]=0;
for(int i=0;i<=n;i++){
for(int j=0;j<=m;j++){
for(int k=0;k<2*maxn;k++){
if(dp[i][j][k]==inf) continue;
int x=i+(i<n&&s[i]=='(');
int y=j+(j<m&&t[j]=='(');
if(k+1<2*maxn&&dp[i][j][k]+1<dp[x][y][k+1]){
dp[x][y][k+1]=dp[i][j][k]+1;
pre[x][y][k+1]=ppo{i,j,k,'('};
}
x=i+(i<n&&s[i]==')');
y=j+(j<m&&t[j]==')');
if(k>0&&dp[i][j][k]+1<dp[x][y][k-1]){
dp[x][y][k-1]=dp[i][j][k]+1;
pre[x][y][k-1]=ppo{i,j,k,')'};
}
}
}
}
string str;
int x=n,y=m,k=0,p=0;
for(int i=0;i<2*maxn;i++){
if(dp[n][m][p]+p>dp[n][m][i]+i) p=i;
}
for(int i=0;i<p;i++) str.pb(')');
k=p;
for(int i=0;i<dp[n][m][p];i++){
ppo p=pre[x][y][k];
str.pb(p.c);
x=p.x;y=p.y;k=p.k;
}
reverse(str.begin(), str.end());
cout<<str<<endl;
return 0;
}

codeforces 1272F dp+记录路径的更多相关文章

  1. PAT L3-001 凑零钱(01背包dp记录路径)

    韩梅梅喜欢满宇宙到处逛街.现在她逛到了一家火星店里,发现这家店有个特别的规矩:你可以用任何星球的硬币付钱,但是绝不找零,当然也不能欠债.韩梅梅手边有104枚来自各个星球的硬币,需要请你帮她盘算一下,是 ...

  2. Codeforces Round #436 (Div. 2) E. Fire(dp 记录路径)

    E. Fire time limit per test 2 seconds memory limit per test 256 megabytes input standard input outpu ...

  3. hdu 1074(状态压缩dp+记录路径)

    题意:给了n个家庭作业,然后给了每个家庭作业的完成期限和花费的实践,如果完成时间超过了期限,那么就要扣除分数,然后让你找出一个最优方案使扣除的分数最少,当存在多种方案时,输出字典序最小的那种,因为题意 ...

  4. CF2B The least round way(dp+记录路径)

    B. The least round way time limit per test 2 seconds memory limit per test 64 megabytes input standa ...

  5. uva 10453 - Make Palindrome(dp, 记录路径)

    题目 题意: 给一个字符串 ,判断最少插入多少个字符 使字符串成为回文串, 并输出回文串. 思路:先用dp判断需要个数, 再递归输出路径. #include <iostream> #inc ...

  6. POJ 题目1141 Brackets Sequence(区间DP记录路径)

    Brackets Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 27793   Accepted: 788 ...

  7. POJ 2111 DP+记录路径

    题意: 思路: 类似滑雪 //By SiriusRen #include <cstdio> #include <cstring> #include <algorithm& ...

  8. hdu1074 状压DP、栈实现记录路径

    题意:给了几门学科作业.它们的截止提交期限(天数).它们的需要完成的时间(天数),每项作业在截止日期后每拖延一天扣一学分,算最少扣的学分和其完成顺序. 一开始做的时候,只是听说过状态压缩这个神奇的东西 ...

  9. poj1417 带权并查集 + 背包 + 记录路径

    True Liars Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 2713   Accepted: 868 Descrip ...

随机推荐

  1. 深度剖析Kubernetes API Server三部曲 - part 2

    欢迎来到深入学习Kubernetes API Server的系列文章的第二部分.在上一部分中我们对APIserver总体,相关术语及request请求流进行探讨说明.在本部分文章中,我们主要聚焦于探究 ...

  2. C#记录日志到本地文件工具类

    using System; using System.Diagnostics; using System.IO; using System.Threading; using System.Web; n ...

  3. (三)easyUI之树形组件

    一.同步树 1.1 概念 所有节点一次性加载完成 1.2 案例 1.2.1 数据库设计 1.2.2 编码 index.jsp <%@ page language="java" ...

  4. HTTP协议探究(六):H2帧详解和HTTP优化

    一 复习与目标 1 复习 HTTP1.1存在的问题 HTTP2.0要兼容HTTP1.1 HTTP2.0的重要概念 分帧层 二进制:流 消息 帧 流的状态.优先级和并发 流量控制 服务器推送 首部压缩 ...

  5. AngularJS视图 ng-view

    AngularJS支持通过在单个页面上的多个视图的单页应用.要做到这一点AngularJS提供ng-view 和 ng-template指令,以及 $routeProvider 服务. ng-view ...

  6. 记录我第一篇用Markdown写的Blog

    Markdown的介绍 喝水不忘挖井人-Markdown的创造者 Markdown 最初是由 John Gruber 和 Aaron Swartz 于 2004 年共同设计的(在这里插一句,Aaron ...

  7. .NET CORE 下 MariaDB DBfirst 生成model层 并配置连接参数

    1.首先新建一个类库,然后通过NuGet安装下面三个包 2.然后在程序包管理器控制台中运行以下代码(ps:记得默认项目选择刚才新建的项目,同时设置为启动项) server 是服务器地址 databas ...

  8. stm32 printf重定向

    printf函数调用fputc int fputc(int ch, FILE *p) { USART_SendData(USART1, ch); //重定向到串口 while(USART_GetFla ...

  9. C语言对齐、补齐

    加快CPU读取数据的速度 aligned(n) 让所作用的结构成员对齐在n字节自然边界上.如果结构中有成员的长度大于n,则按照最大成员的长度来对齐 struct s { char c; int i; ...

  10. git的使用(win7 64位)

    下载安装 1.官方下载网址:https://git-scm.com/downloads: 2.安装十分简单,按照默认配置,一直点击next,最后点击install,即安装成功: 3.安装成功之后,则自 ...