题意:求最少添加多少个括号可以使得原序列成为合法的括号序列,并输出这个合法的括号序列.
分析: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.