I and OI
Past...

题意:求最少添加多少个括号可以使得原序列成为合法的括号序列,并输出这个合法的括号序列.

分析:DP,记录路径.

用f[i,j]表示i~j之间的序列至少添加多少个括号.

显然,f[i,i]=1.

1.f[i,j]=f[i+1,j-1] (s[i],s[j]可以配对)

  d[i,j]=-1;

2.f[i,j]=min{f[i,k]+f[k+1,j]} (i<=k<=j-1)

  d[i,j]=k;(k是f[i,j]的决策点)

方案输出见代码.

code:

const oo=10000000;
var   f,d:array[0..110,0..110] of longint;
      s:array[0..110] of char;
      i,j,k,n,l:longint;

      procedure print(l,r:longint);
      begin
            if l>r then exit;
            if l=r then
            begin
                  if (s[l]='(')or(s[l]=')') then write('()')
                  else write('[]');
                  exit;
            end;
            if d[l,r]=-1 then
            begin
                  write(s[l]);
                  print(l+1,r-1);
                  write(s[r]);
            end
            else
            begin
                  print(l,d[l,r]);
                  print(d[l,r]+1,r);
            end;
      end;

begin
      while not eoln do
      begin
            inc(n);
            read(s[n]);
            f[n,n]:=1;
            f[n,n+1]:=0;
      end;

      for l:=1 to n-1 do
         for i:=1 to n-l do
         begin
               j:=i+l;
               f[i,j]:=oo;
               if (s[i]='(')and(s[j]=')')or(s[i]='[')and(s[j]=']') then
               begin
                     f[i,j]:=f[i+1,j-1];
                     d[i,j]:=-1;
               end;
               for k:=i to j-1 do
                  if f[i,j]>f[i,k]+f[k+1,j] then
                  begin
                        f[i,j]:=f[i,k]+f[k+1,j];
                        d[i,j]:=k;
                  end;
         end;
      Print(1,n);
      writeln;
end.
posted on 2011-08-10 13:02  exponent  阅读(490)  评论(0编辑  收藏  举报