这题简直了…………

首先根据操作可知,我们肯定是先造出某个偶数长度的回文串,然后添加若干字符得到设回文串长为len[x]

则ans=min(n-len[x]+f[x]);

那么问题就是制造这个串的回文串,最少的操作次数

对于回文串x,我们有这种情况

f[x]=min(f[y]+1,(y是x去掉首尾),f[y]+len[x]-len[y](y是最长回文前缀,(其实这个可以不考虑,因为这就相当于直接制造y)

=(f[y]+len[x] div 2-len[y]+1,y是长度不超过x一半的最长回文后缀)

dp大家都会,但状态怎么表示呢?………………

显然一个串回文串不超过n,但是怎么表示之间的关系呢?

我曾yy了一种manacher+后缀自动机的做法,结果是又WA又T一时爽……

无奈学了一下回文树,感觉是非常简洁明快的

学习可以转到:http://pan.baidu.com/s/1hqzRlvm

感觉有点像ac自动机,还是比较好懂的,这样就简单了

但我pascal本地AC交上去不停RE不知为何……

  1 var go:array[0..200010,1..4] of longint;
  2     len,fa,sub,a,q,f:array[0..200010] of longint;
  3     last,t,ans,i,tt,n:longint;
  4     s:ansistring;
  5 
  6 function min(a,b:longint):longint;
  7   begin
  8     if a>b then exit(b) else exit(a);
  9   end;
 10 
 11 function what(ch:char):longint;
 12   begin
 13     if ch='A' then exit(1);
 14     if ch='T' then exit(2);
 15     if ch='C' then exit(3);
 16     if ch='G' then exit(4);
 17     exit(-1);
 18   end;
 19 
 20 procedure getchar;
 21   var i:longint;
 22   begin
 23     readln(s);
 24     n:=length(s);
 25     a[n+1]:=-1;
 26     for i:=1 to n do
 27       a[i]:=what(s[i]);
 28   end;
 29 
 30 function getf(x:longint):longint;
 31   begin
 32     while a[i-len[x]-1]<>a[i] do x:=fa[x];
 33     exit(x);
 34   end;
 35 
 36 procedure newnode(l:longint);
 37   begin
 38     inc(t);
 39     fillchar(go[t],sizeof(go[t]),0);
 40     len[t]:=l;
 41     fa[t]:=0;
 42   end;
 43 
 44 procedure add(c:longint);
 45   var now,cur,x:longint;
 46   begin
 47     cur:=getf(last);
 48     if go[cur,c]=0 then
 49     begin
 50       newnode(len[cur]+2); now:=t;
 51       fa[now]:=go[getf(fa[cur]),c];
 52       go[cur,c]:=now;
 53       if len[now]<=2 then f[now]:=len[now]
 54       else begin
 55         x:=sub[cur];
 56         while (a[i-len[x]-1]<>a[i]) or (2*(len[x]+2)>len[now]) or (len[x] mod 2=1) do x:=fa[x];
 57         sub[now]:=go[x,c];
 58       end;
 59     end;
 60     last:=go[cur,c];
 61   end;
 62 
 63 procedure bfs;
 64   var h,r,x,y,i,w:longint;
 65   begin
 66     h:=1;
 67     r:=1;
 68     q[1]:=0;
 69     f[0]:=1;
 70     while h<=r do
 71     begin
 72       x:=q[h];
 73       for i:=1 to 4 do
 74       begin
 75         y:=go[x,i];
 76         if y<>0 then
 77         begin
 78           inc(r);
 79           q[r]:=y;
 80           if len[y]>2 then
 81           begin
 82             f[y]:=min(f[x]+1,len[y] div 2-len[sub[y]]+f[sub[y]]+1);
 83             ans:=min(ans,n-len[y]+f[y]);
 84           end;
 85         end;
 86       end;
 87       inc(h);
 88     end;
 89   end;
 90 
 91 begin
 92   readln(tt);
 93   while tt>0 do
 94   begin
 95     dec(tt);
 96     getchar;
 97     t:=-1;
 98     newnode(0);
 99     newnode(-1);
100     fa[0]:=1;
101     last:=0;
102     for i:=1 to n do
103       add(a[i]);
104     ans:=n;
105     bfs;
106     writeln(ans);
107   end;
108 end.
View Code

 

posted on 2015-06-20 15:58  acphile  阅读(247)  评论(0编辑  收藏  举报