zoukankan      html  css  js  c++  java
  • DP专题——括号序列

    毕竟是个渣,写完一遍之后又按LRJ的写了一遍,再写了一遍递归版,最终加上输出解部分

    括号序列

    定义如下规则序列(字符串):
    空序列是规则序列;
    如果S是规则序列,那么(S)和[S]也是规则序列;
    如果A和B都是规则序列,那么AB也是规则序列。

    例如,下面的字符串都是规则序列:
    (), [], (()), ([]), ()[], ()[()]

    这几个则不是规则序列:
    (, [, ], )(, ([()

    现在,给出一些由‘(’,‘)’,‘[’,‘]’构成的序列,请添加尽量少的括号,得到一个规则序列。

    分析

    • 很容易想到的递归版本
    uses
    		math;
    var
    	 s:string;
    function answer(l,r:longint):longint;
    var mini,k:longint;
    begin	
         if l=r then exit(1)
         else if (s[l]='(')and(s[r]=')')or(s[l]='[')and(s[r]=']') then exit(answer(l+1,r-1))
         else if l<r then begin
         			mini:=maxint;
         			for k:=l to r-1 do
              		 mini:=min(mini,answer(l,k)+answer(k+1,r));
              exit(mini);
         end else exit(0);
    end;
    begin
         readln(s);
         writeln(answer(1,length(s)));
    end.
    
    • 稍微做下改动,同时为了方便输出解(输出时再判定一次)

    d(s)表示s的解

    现存在两种情况

    当s形为(s')时,转移到d(s')
    当length(s)>1 时,转移到d(sA)+d(sB)

    边界条件
    length(s)=1时 d(s)=1
    其他为0

    {2015-9-24 括号序列}
    {program by Chuck}{误}
    
    program noip_dp_1;
    uses
    		math;
    const
    		 maxn=1000;
    type
    		LL=longint;
    var
    	 d:array[1..maxn,1..maxn] of LL;
       i,j,k,n:LL;
       st:ansistring;
       boo:boolean;
    function match(l,r:char):boolean;
    begin
    		 if (l='(') and (r=')') or (l='[') and (r=']') then exit(true)
         else exit(false);
    end;
    
    procedure print(l,r:Longint);
    var
    	 k,ans:longint;
    begin
    		 if l>r then exit;
    		 if l=r then
         begin
         		if (st[l]=')')or(st[l]='(') then write('()')
            else write('[]');
            exit;
         end;
         ans:=d[l][r];
         if match(st[l],st[r]) and (ans=d[l+1][r-1])then begin
         		write(st[l]);
            print(l+1,r-1);
            write(st[r]);
         end else
         		 for k:=l to r-1 do
             		 if ans=d[l][k]+d[k+1][r] then
                 begin
                 			print(l,k);
                      print(k+1,r);
                      exit;
                 end;
    end;
    begin
    		 assign(input,'dp1.in');
         assign(output,'dp1.out');
         reset(input);
         rewrite(output);
         readln(st);
         n:=length(st);
         fillchar(d,sizeof(d),0);
    		 for i:=1 to n do
         			d[i][i]:=1;
         for i:=n-1 downto 1 do
         		 for j:=i+1 to n do
             begin
             			d[i][j]:=n;
                  boo:=match(st[i],st[j]);
                  if boo then
                  	 d[i][j]:=min(d[i][j],d[i+1][j-1]);
                  for k:=i to j-1 do
                  		d[i][j]:=min(d[i][j],d[i][k]+d[k+1][j]);
             end;
         writeln(d[1][n]);
         print(1,n);
         close(input);
         close(output);
    end.
    

    为了这个程序煞费苦心,我真是渣渣到爆了……
    自己好不容易写的一大段因为head hole big open被删了,删完才发现稍作改动就是对的啊……
    于是因为生病实在没有坚持下来,看了题解再打的一遍。。
    明天九月最后一天,距离初赛还有11天,
    我天嘞困死了……

  • 相关阅读:
    Elasticsearch轻量搜索与分析
    Elasticsearch文档详解
    Elasticsearch基本概念
    Elasticsearch集群健康
    Elasticsearch搜索与分析
    Redis 面试题 记录
    Redis集群 详解
    从根上理解高性能、高并发(六):通俗易懂,高性能服务器到底是如何实现的
    昔日移动端IM明星 “米聊” 即将停止服务
    从根上理解高性能、高并发(五):深入操作系统,理解高并发中的协程
  • 原文地址:https://www.cnblogs.com/Chuckqgz/p/4847550.html
Copyright © 2011-2022 走看看