Brackets Sequence--poj--1141

[题目记录]括号序列(Brackets Sequence) 定义如下正规括号序列(字符串):空序列是正规括号序列。 如果S是正规括号序列,那么(S)和[S]也是正规括号序列。 如果A和B都是正规括号序列,那么AB也是正规括号序列。例如,下面的字符串都是正规括号序列:(),[],(()),([]),()[],()[()],而如下字符串 则不是正规括号序列:(,[,],)(,([()。输入一个长度不超过100的,由“(”、“)”、“[”、“]”构成的序列,添加... 阅读详情

Brackets Sequence

Time Limit: 1000MS

Memory Limit: 65536K

Total Submissions: 11854

Accepted: 3164

Special Judge

Description

Let us define a regular brackets sequence in the following way:

1. Empty sequence is a regular sequence.
2. If S is a regular sequence, then (S) and [S] are both regular sequences.
3. If A and B are regular sequences, then AB is a regular sequence.

For example, all of the following sequences of characters are regular brackets sequences:

(), [], (()), ([]), ()[], ()[()]

And all of the following character sequences are not:

(, [, ), )(, ([)], ([(]

Some sequence of characters '(', ')', '[', and ']' is given. You are to find the shortest possible regular brackets sequence, that contains the given character sequence as a subsequence. Here, a string a1 a2 ... an is called a subsequence of the string b1 b2 ... bm, if there exist such indices 1 = i1 < i2 < ... < in = m, that aj = bij for all 1 = j = n.

Input

The input file contains at most 100 brackets (characters '(', ')', '[' and ']') that are situated on a single line without any other characters among them.

Output

Write to the output file a single line that contains some regular brackets sequence that has the minimal possible length and contains the given sequence as a subsequence.

Sample Input

([(]

Sample Output

()[()]

Source

Northeastern Europe 2001

 

先读懂题意:

很简单,就是给出一个序列,要求添加最少的符号使其变成题目要求的规则序列。

 

解题思路:
先用递归的方法来分析问题,设输入序列SiSi+1...Sj最少需要添加d[i,j]个括号,根据不同情况,可以将问题分解为以下子问题:

1)S形如(S’)或者[S’]

只需要把S’变成规则的序列,则S就是规则的了;

2)S形如(S’

先把S’变成规则序列,接着在最后添加”)”,则S就变成规则序列了;

3)S形如S’)或者[S’或者S’]

和上面的情况类似解法

4)只要序列S的长度大于1,都可以把S分成两部分:Si...Sk和Sk+1...Sj,然后分别将子序列变成规则序列,则拼接在一起的S就是规则序列了。

下面给出递归的伪代码:

function Bracket(i, j : Integer);     //i和j是本序列在原始输入序列中的开始和结束下标

begin

         if i>j then return 0

         else if i=j then return 1;

         else begin

                   Answer := MAX;

                   if s[i]s[j]='()' or s[i]s[j]='[]' then //对应上面情形1

                            Answer := min(Answer, Bracket(i+1, j-1));

                   if s[i]='(' or s[i]='[' then        //对应上面情形2/3

                            Answer := min(Answer, Bracket(i+1, j) + 1); //加1表示在右边加了')'或']'

                   if s[j]=')' or s[j]=']' then        //同上2/3

                            Answer := min(Answer, Bracker(i, j-1)+1);

                   For k:=i to j-1 do   //对应上面情形4

                            Answer := min(Answer, Bracket(i, k) + Bracket(k+1, j));

         end;

end;

上面递归的算法效率很低(递归进行了很多重复计算),时间复杂度是指数级的,因此我们必须在递归的基础上进行改进,即采用动态规划。

一、记忆化搜索

在每次调用Bracket函数之前,先检查之前是否已经计算过这个值了,如果是则直接从之前保存的表中找出:

function Bracket(i , j : Integer);

begin

         if Calculated[i, j] then return d[i, j];

         //此处插入上面的递归代码

         d[i, j] := Answer

         Calculated[i, j] := true;

end;

 

二、自底向上的递推法

由于计算d[i, j]之前需要知道d[i+1, j],d[i, j-1]和d[i+1, j-1]的值,所以按照j-i递增的顺序计算出d[i, j]:

for i:=1 to n do d[i, i-1]:=0; //置初始值

for i:=1 to n do d[i, i]:=1;

for p:=1 to n-1 do

         for i:=1 to n-p do

         begin

                   j:=i+p

                   d[i, j]:=MAX;

                   if s[i]s[j]='()' or s[i]s[j]='[]' then

                            d[i, j] := min(d[i, j], d[i+1, j-1]);

                   if s[i]='(' or s[i]='[' then

                            d[i, j] :=min(d[i, j], d[i+1, j] + 1);

                   if s[j]=')' or s[j]=']' then

                            d[i, j] := min(d[i, j], d[i, j-1]+1);

                   For k:=i to j-1 do

                            d[i, j] := min(d[i, j], d[i, k] + d[k+1, j]);

         end;

 

AC代码如下:

#include <iostream>

#include <string>

 

const int MAX = 1000;

int flag[MAX][MAX]; //in[i]到in[j]间字符数

int mem[MAX][MAX]; //mem[i][j]记录in[i]和in[j]之间的序列是否需要分成两部分

 

std::string in;//存储输入的字符串

 

int min(int x, int y)

{

         return (x>y ? y : x);       

}

 

//打印出结果字符

void find(int xx, int yy)

{

         if(xx > yy)

                   return;

        

         if(mem[xx][yy] == -1) //当前序列不需要分成两部分

         {

                   if(xx == yy)//当前序列只剩一个字符

                   {

                            if(in[xx] =='(' || in[xx] == ')')

                                     std::cout<<"()";

                            else if(in[xx]=='[' || in[xx]== ']')

                                     std::cout<<"[]";   

                   }       

                   else  //当前序列不止一个字符

                   {

                            std::cout<<in[xx];        //输出当前序列第一个字符

                            find(xx+1, yy-1);     //对中间的部分递归

                            std::cout<<in[yy]; //输出当前序列最后一个字符

                   }

         }

         else  //当前序列需要分成两部分

         {

                   int tmp = mem[xx][yy];       //分割的下标

                   find(xx, tmp);

                   find(tmp+1, yy);

         }       

        

         return;

}

 

int main()

{

         std::cin>>in;

         int len = in.length();

        

         memset(flag, 0, sizeof(flag));

         memset(mem, -1, sizeof(mem));

        

         for(int k=0; k<len; k++)

         {

                   for(int i=0, j=k; j<len; i++, j++)

                   {

                            if(i == j)

                                     flag[i][j] = 1;  //记录in[i]到in[j]中间字符的个数

                            else

                            {

                                     int tmp = 10000000;

                                     if((in[i]=='(' && in[j]==')') ||

                                               (in[i]=='[' && in[j]==']'))

                                     {

                                               tmp = min(tmp, flag[i+1][j-1]);  

                                     }

                                    

                                     //只要当前序列S的长度大于1,都可以把S分成两部分:Si...Sk和Sk+1(下标)...Sj

                                     //然后分别将子序列变成规则序列,则拼接在一起的就是规则序列了

                                     for(int t=i; t<j; t++)

                                     {

                                               if(tmp>flag[i][t] + flag[t+1][j])//找出字符数最小值

                                               {

                                                        tmp = flag[i][t] + flag[t+1][j];

                                                        mem[i][j] = t;         //记录分割的下标t

                                               }

                                     }

                                     flag[i][j] = tmp;//in[i]到in[j]间字符数为tmp

                            }       

                   }       

         }

        

         find(0, len-1);

         std::cout<<std::endl;

        

         system("pause");

         return 0;

}

DrMOS电路仿真 将驱动电路与功率MOS集成化后既是DrMOS。把驱动芯片以及上下桥MOSFET封装在一起,这样每一相供电就有了单独的驱动芯片,并且这种高度整合的MOSFET可以通过更高的电流、发热比传统的MOSFET也小很多且更节能 自举升压同步BUCK高低侧栅驱动电路原理及仿真 ... 阅读详情

相关推荐

2025小红书跳转卡片实战指南:从零搭建独立后台与自动化发卡系统

本文提供了一份2025年小红书跳转卡片的实战搭建指南,详细解析了独立后台系统的核心架构与自动化发卡流程。文章从零开始,手把手教你使用Node.js、Vue.js等技术栈构建包含后台管理、用户制卡中心与前端交互的完整系统,旨在帮助运营者实现合规引流,并掌握数据自主权与自动化运营能力。

weixin_29234423的博客 517

ZOJ1463:Brackets Sequence(区间DP)

Let us define a regular brackets sequence in the following way: 1. Empty sequence is a regular sequence. 2. If S is a regular sequence, then (S) and [S] are both regular sequences. 3. If A an

ACM!荣耀之路! 2753

LabVIEW数据采集-数字I/O/计数器

labview 数据采集 数字I/O 计数器

weixin_43781045的博客 5617

Java实现算法之Brackets Sequence问题

Problem: Description Let us define a regular brackets sequence in the following way: 1. Empty sequence is a regular sequence. 2. If S is a regular sequence, then (S) and [S] are both regular s

NFMSR的博客 564

STM32与AD7606的SPI通信优化:提升高精度数据采集效率

本文深入探讨了STM32与AD7606的SPI通信优化策略,旨在提升高精度数据采集系统的效率与稳定性。文章从硬件连接、电源去耦、PCB布局等基础环节入手,详细解析了软件驱动中SPI模式配置、DMA应用及精准时序控制等关键优化技术,并提出了系统级的性能提升方案,帮助开发者解决高速采样下的数据跳动、效率瓶颈等实际问题。

weixin_29192211的博客 392

linux入侵排查-综合日志分析

2.分析攻击者首次成功登录web管理后台的时间 还可以知道攻击者可能是通过10.2.4.11这个跳板服务器跳过来的,然后我们继续排查,可以发现日志中POST请求大多都是1047字节,然后往后大多是300字节,POST请求的响应状态码有200和302这两个,其中的302是爆破成功后持续爆破产生的日志,再1047字节和300字节中间夹着一个978字节,就是200响应和302响应的中间。7.分析攻击者留下的持久化后门的时间和后门执行情况 排查计划任务,发现有一个计划任务还是被加密的,应该是反弹shell的。

chinese_cabbage0的博客 643

Brackets Sequence 解题报告

原题链接:http://poj.org/problem?id=1141 思路:先放一段核心代码解释,然后再附上代码。 解释:核心代码解释:字符串数组s存储着输入的字符串, dp[i][j]则用来表示区间[i,j]之间的括号匹配数, 然后当区间[i,j]中两段不匹配时,c[i][j]就表示区间[i,j]里最佳的添加括号的位置,表示需要在[i,c[i][j]][c[i][j]+1,j]中继续枚举。 而...

qq_42967637的博客 295

基于Simulink的异步电机参数在线辨识与自适应控制仿真

本文基于Simulink平台,详细介绍了异步电机参数在线辨识与自适应控制系统的仿真实现。针对异步电机运行中参数时变问题,采用模型参考自适应系统(MRAS)实时辨识转子电阻和互感,并结合自适应PI控制策略动态调整控制器参数。通过搭建完整的矢量控制(FOC)仿真模型,验证了系统在稳态辨识、参数摄动和动态响应等工况下的性能:参数辨识误差<1.2%,转速跟踪误差<20rpm,动态响应时间<10ms。文章还提供了详细的Simulink建模步骤、核心代码实现及性能分析,为高级电机控制系统的设计与优化提

amy_mhd的博客 72

A - Brackets

A - Brackets Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Description We give the following inductive definition of a “regular bracket

Limhhhhh的博客 1549

《基于FPGA的数字信号处理》专栏的导航与说明

《基于FPGA的数字信号处理》专栏的导航与说明

孤独的单刀 4160

GD32F4xx 移植agile_modbus软件包与电能表通信

GD32F4XX 移植agile modbus软件包实现与DTSU电能表通信调试记录

madao1234的博客 1304

POJ 1141 Brackets Sequence

POJ  1141;链接:http://poj.org/problem?id=1141 题目: Brackets Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 23638   Accepted: 6665   Special Judge

u010084308的专栏 1188

PyTorch深度学习实战(7)——批大小对神经网络训练的影响

在神经网络中,批( batch )是指一次输入网络进行训练或推断的一组样本。批处理( batch processing )是指将这一组样本同时输入网络进行计算的操作。本节中首先介绍批( Batch )的基本概念,并且介绍批大小在神经网络训练过程中的影响。

盼小辉丶的博客 1万+

POJ 1141 Brackets Sequence

题目描述: 定义合法的括号序列如下: 1 空序列是一个合法的序列 2 如果S是合法的序列,则(S)和[S]也是合法的序列 3 如果A和B是合法的序列,则AB也是合法的序列 例如:下面的都是合法的括号序列 (),  [],  (()),  ([]),  ()[],  ()[()] 下面的都是非法的括号序列 (,  [,  ),  )(,  ([)],  ([(]  给定一个

路漫漫其修远兮,吾将上下而求索 4341

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

POJ-1141-Brackets Sequence

POJ-1141-Brackets Sequence 传送门 这道题是区间dp~ 括号匹配 题目大意:给你一个括号序列,让你构造一个长度最小的匹配的括号序列,使得给定的括号序列为构造的括号序列的子序列(注意是子序列) 文件形式读入 然后这道题用dp解决无疑了。 dp[i][j]表示第i个字符到第j个字符构成匹配的括号序列最小需要添加多少字符。 初始化部分: dp[i + 1][i] = 0;(这个...

qq_44624316的博客 244

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

动态规划 Brackets Sequence poj 1141

题目连接:http://poj.org/problem?id=1141 题目大意:给出一串括号序列(只包含小括号和中括号),求包含次子序列的长度最小的regular brackets sequence。其中regular brackets sequence定义如下: 1.空序

凌风 2921

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

poj 1141Brackets Sequence

Brackets Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 31629   Accepted: 9114   Special Judge Description Let us define a regular brackets seque

wo的只属于我 395

poj 1141 Brackets Sequence(DP第一弹)

poj   1141   Brackets Sequence                      题目链接:http://poj.org/problem?id=1141 DP 题目大意:一个字符串只有方括号和圆括号四种字符,规定合法序列,要求将输入序列修改成最短合法序列输出。 合法序列定义:     (1)空序列是一个合法的序列。     (2)如果S是一个合法序列,那么(S)和[

slicer的技术交流栈 824

POJ 1141_Brackets Sequence

Description Let us define a regular brackets sequence in the following way:  1. Empty sequence is a regular sequence.  2. If S is a regular sequence, then (S) and [S] are both regular sequences

骐骥一跃不能十步,驽马十驾功在不舍 761

poj1141-Brackets sequence

题目链接 题意:给定一括号序列,求出添加括号数最小的完整序列 解法:区间DP 定义dp[i][j]表示题目所给字符串s中从左至右字符i至j这一区间段括号序列构成完整序列所需添加的最小括号数; 根据i与j的大小对dp[i][j]进行初始化,i==j显然为1,i>j不符合定义中从左至右意为空序列即0,i<j因是取最小值则初值设为相对较大; 设阶段r为序列长度,状态为i为...

My优快云5008的博客 301

Poj 1141 Brackets Sequence

DescriptionLet us define a regular brackets sequence in the following way: 1. Empty sequence is a regular sequence. 2. If S is a regular sequence, then (S) and [S] are both regular sequences. 3.

Follow My Heart 395

POJ 1141 —— Brackets Sequence

题目:http://poj.org/problem?id=1141 区间DP + 构造出DP的解 这里有两种思路都是对的:   第一种(推荐):dp[i][j] := 区间i~j最少需要加多少字符使得它符合括号匹配,然后构造出一个DP的解就好了   第二种:dp[i][j] := 区间i~j符合括号匹配的最长子序列的长度,然后在构造最长子序列的过程中标记哪些字符本身就已经匹配完毕了,然后对

AcIsFun的博客 316

poj 1141 Brackets Sequence

感想:较好的入门题,关键这里可以让你学到记录路径的方法,也可以算做dp记路径的入门题了吧。 思路:   这题的思路关键在于   (A) 或(B)  AB这几种请况,所以在dp的过程中 要找这几种的最小值, 首先   dp[ i ][ i ]肯定是1,因为只有一个单括号的话,必须要来一个括号来进行匹配; 状态转移方程   dp[ i ][ j ] =  min(d

purevegetable 1218

poj1141 Brackets Sequence

(http://www.elijahqi.win/2017/12/28/poj1141-brackets-sequence/) DescriptionLet us define a regular brackets sequence in the following way: Empty sequence is a regular sequence. If S is a regular seque

Elijahqi 225

POJ1141 Brackets Sequence

大致的意思是将一个非规范的序列转化成规范的序列,如 ([(],这是一个非规范的序列,处理之后要求输出规范的序列:()[()],要求就是添加最少的括号。     黑书上通过这题来介绍选择DP的原因之一:递归。     因为序列Si····Sj,可以分成:Si···Sk,Sk+1···Sj,只要d(i,k)+d(k+1,j)最小,则d(i,j)=min(d(i,j),d(i,k)+d(k+1,j)

flyRP的专栏 578

POJ1141 Brackets Sequence

题目大意:定义一些规则序列:如果S是规则序列,那么[S]或者(S)也是规则序列,如果A和B都是规则序列,那么AB是规则序列。给出含有圆括号"()"和方括号"[]"的字符串 求添加最少括号的规则序列,并打印出来。 思路:含有重复子问题,递归动机的DP。 当字符串中ww[i]=='(' && ww[j]==')'  或者  ww[i]=='['&&ww[j]==']',那么显然只需要看dp[i+

muxi@Achilles的专栏 949
上一篇: Parliament--POJ--1032
下一篇: 《Windows核心编程》---动态链接库和钩子基础
ACE1985
博客等级 码龄17年 1307粉丝 308原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值