整理的算法模板合集: ACM模板


UVA1626 Brackets sequence

我们将正规括号序列定义如下:

  • 空序列是正规括号序列。
  • 如果 SSS 是一个正规括号序列,那么 (S)[S] 都是正规括号序列。
  • 如果 A 和 B 都是正规括号序列,那么 AB 是一个正规括号序列。

例如,下面这些序列都是正规括号序列: (),[],(()),([]),()[],()[()]

而下面这些不是正规括号序列: (,[,),)(,([)],([]

给你一些含有字符 '('')''['']' 的括号序列。你需要找一个最短的正规括号序列,使给定括号序列作为一个子序列包含在其中。

Solution

显然还是区间DP。

设 f[i,j]f[{i,j}]f[i,j] 表示子串 si∼sjs_i \sim s_jsi​∼sj​中,使得这段子串合法还需添加的最少字符数。

对于区间左右端点 i,ji,ji,j

  • 若 si=s_i=si​= '(' 且 sj=s_j=sj​=')' ,或者 si=s_i=si​= '[' 且 sj=s_j=sj​= ']' ,则 f[i,j]=f[i+1,j−1]f[{i,j}]=f[{i+1,j-1}]f[i,j]=f[i+1,j−1]。
    注意当 j=i+1j=i+1j=i+1 时,就会出现 f[i+1,i]f[{i+1,i}]f[i+1,i] ,所以初始化时要将 f[i+1,i]=1f[{i+1,i}]=1f[i+1,i]=1 。

  • 若 si=s_i=si​= '(' 或 si=s_i=si​= '[' ,f[i,j]=min⁡(f[i,j],f[i+1,j]+1)f[{i,j}]=\min(f[{i,j}],f[{i+1,j}]+1)f[i,j]=min(f[i,j],f[i+1,j]+1)。

  • 若 sj=s_j=sj​= ')' 或 si=s_i=si​= ']' , fi,j=min⁡(f[i,j],f[i,j−1]+1)f_{i,j}=\min(f[{i,j}],f[{i,j-1}]+1)fi,j​=min(f[i,j],f[i,j−1]+1)。

  • p(i≤p<j)p(i \leq p < j)p(i≤p<j), f[i,j]=min⁡(f[i,j],f[i,p]+f[p+1,j])f[{i,j}]=\min(f[{i,j}],f[{i,p}]+f[{p+1,j}])f[i,j]=min(f[i,j],f[i,p]+f[p+1,j])

初始化: fi,i=1f_{i,i}=1fi,i​=1

需要注意的是输入有可能是空串,所以需要用两次 getline

最后输出方案

输出时考虑四种情况:

  • i>j不是子串,return 0;
  • i == j子串长度为1说明是一个孤立点,补齐输出,return 1;
  • s = (s') 或 s = [s']那么返回的是f(i + 1, j - 1)
  • 其他情况,枚举断点

Code

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<cstring>using namespace std;
typedef long long ll;
const int N = 507, M = 5000007, INF = 0x3f3f3f3f;
const double eps = 1e-6;int n, m, t;
int a[N];
int f[N][N];
int b[N];
string s;bool match(char a, char b)
{if(a == '[' && b == ']')return true;if(a == '(' && b == ')')return true;return false;
}//按照转移的方法完全的再倒推一遍
void print(int i, int j)
{if(i > j)return ;if(i == j){if(s[i] == '(' || s[i] == ')')printf("()");else printf("[]");return ;}int ans = f[i][j];if(match(s[i], s[j]) && ans == f[i + 1][j - 1]){printf("%c", s[i]);print(i + 1, j - 1);//往里缩printf("%c", s[j]);//包起来return ;}for(int k = i; k < j; ++ k){if(ans == f[i][k] + f[k + 1][j]){print(i, k);print(k + 1, j);return ;}}
}int main()
{scanf("%d", &t);getchar();while(t -- ){memset(f, 0x3f, sizeof f);getline(cin, s);//注意因为可能有空串所以要输入两次getline(cin, s);n = s.length();if(n == 0){puts("");puts("");continue;}//f[i][j]表示s[i~j]至少要添加多少个括号for(int i = 1; i < n; ++ i){f[i][i] = 1;f[i][i - 1] = 0;}f[0][0] = 0;for(int i = n - 1; i >= 0; -- i){//左for(int j = i + 1; j < n; ++ j){//右//f[i][j] = INF;if(match(s[i], s[j]))//方案1,相同可内缩f[i][j] = min(f[i][j], f[i + 1][j - 1]);for(int k = i; k < j; ++ k){//方案2,至少大于2,可以分开f[i][j] = min(f[i][j], f[i][k] + f[k + 1][j]);}}}print(0, n - 1);puts("");if(t)puts("");}return 0;
}

UVA1626 括号序列 Brackets sequence(区间DP匹配括号,输出匹配方案)相关推荐

  1. UVA1626 / ZOJ1463 Brackets sequence 区间DP

    简单区间DP (有空串... ...) Brackets sequence Time Limit: 4500MS   Memory Limit: Unknown   64bit IO Format:  ...

  2. 紫书动规 例题9-10 UVA - 1626 Brackets sequence 区间dp

    题目链接: https://vjudge.net/problem/UVA-1626 题意: 题解: dp[i][j]:= i~j需要最少的括号 区间dp: dp[i][j] = min(dp[i][j ...

  3. Brackets POJ - 2955 (区间DP+最大括号匹配子序列)

    传送门 题目:给一个长度n(<=100)的只包含'[',']','(',)'的字符串,求最长的完全匹配的子序列.输出长度 题解:区间dp,dp[i][j]表示i~j的最长匹配数,一支dp[i][ ...

  4. 【动态规划笔记】区间dp:括号匹配(删除字符和括号匹配)

    代码: //区间dp:括号匹配 #include<iostream> #include<string> #include<string.h> using names ...

  5. POJ 2955 Brackets (区间DP)

    题目链接:http://poj.org/problem?id=2955 Brackets Time Limit: 1000MS   Memory Limit: 65536K Total Submiss ...

  6. Brackets (区间DP)

    个人心得:今天就做了这些区间DP,这一题开始想用最长子序列那些套路的,后面发现不满足无后效性的问题,即(,)的配对 对结果有一定的影响,后面想着就用上一题的思想就慢慢的从小一步一步递增,后面想着越来越 ...

  7. POJ - 2955 Brackets (区间DP)

    题目: 给出一个有括号的字符串,问这个字符串中能匹配的最长的子串的长度. 思路: 区间DP,首先枚举区间长度,然后在每一个长度中通过枚举这个区间的分割点来更新这个区间的最优解.还是做的少. 代码: / ...

  8. URAL 1721 Two Sides of the Same Coin(二分图匹配,输出匹配对象)

    题意:给出n个人的信息,名字.特征.排名. 在排名相差2的前提下,特征为testdata可以与特征为statements的组队,特征为anything可以任何一人组队: 求最多匹配对数,并将每队名字输 ...

  9. 【区间dp】括号序列再战猪猪侠

    ydc的题解是只需要两维状态 = = 可是...可是我必须写三维才能AC TAT all表示区间[L, R]是(A) 还是 AB.. 为了O(1)判断处理一个二维数组的前缀和.. 还有这个鬼要特判 u ...

最新文章

  1. Android Support v4、v7、v13的区别和应用场景
  2. Resource接口,及资源
  3. scala中:: , +:, :+, :::, +++的区别
  4. NAND FLASH读写原理
  5. Spring配置文件总结-applicationContext.xml
  6. 生成8位的不重复乱码
  7. x的平方加y平加xy的java语言_面试被虐题:说说 JVM 系语言的函数式编程
  8. C++ 顺序容器基础知识总结
  9. 2019新闻自动挂机阅读脚本
  10. 菲尼克斯电源模块QUINT-PS3AC24DC40的组装说明
  11. 发射功率 接收灵敏度 RF射频传输 原理 介绍 三分钟看懂 详解!
  12. 2022.3.21密码学des对称密码与rsa非对称密码【网络攻防CTF】(保姆级图文)
  13. 【前端】你真的理解JavaScript中的变量和数据类型吗
  14. 农历大小月的确定方法
  15. 用u盘制作u启动重装系统的步骤实现
  16. Matlab与Access数据库编程指南
  17. 泰坦尼克号乘客生存情况预测分析之第三部分建模及模型评价
  18. 二、八、十、十六进制之间的转换
  19. 适配mpvue平台的的微信小程序日历组件mpvue-calendar
  20. vsftpd配置文件讲解

热门文章

  1. 点云及三维图像处理综述
  2. 图像分割20年,盘点影响力最大的10篇论文
  3. 实战:动手搭建一个开源动作相机
  4. C++——创建类的时候用new与不用new 的区别(转)
  5. 详解JVM内存管理与垃圾回收机制3 - JVM中对象的内存布局
  6. ios 3DTouch初识
  7. 一个检查分区内存并且发送邮件的shell脚本
  8. 安装QT的时候出现PATH_MAX错误
  9. Zookeeper常用命令使用
  10. redis的分布式解决方式--codis (转)