这题简直了…………
首先根据操作可知,我们肯定是先造出某个偶数长度的回文串,然后添加若干字符得到设回文串长为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.