HDOJ3341Lost's revenge(AC自动机,DP)
Posted myx12345
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDOJ3341Lost's revenge(AC自动机,DP)相关的知识,希望对你有一定的参考价值。
题意:给出一个n个模式串,一个目标串,问把目标串重新排位最多能产生多少个模式串,可以重叠且所有串只包含A C G T。
n<=10,len[i]<=10
len(s)<=40
Cas<=30
思路:TLE,估计被卡常了
可以将题意理解为重新构造一个ACGT个数都与原目标串相同的新串,则目标串中有用的信息只有ACGT个数
建出Trie图,跑一遍AC自动机,再用一个二维dp[i,j]表示trie上i号节点,字母使用情况为j的模式串最多出现次数
其中j为状态压缩量,是一个四维的量压成一维,因为不压的话会MLE
dp[v,h(a,b,c,d)]=max(dp[v,h(a,b,c,d)],dp[u,h(a-1,b,c,d)]+size[v])等四种转移
其中v=map[u,i],size[v]表示trie上到v节点路径出现次数之和
边界条件dp[1,h(0,0,0,0)]=1
1 var map:array[1..600,1..4]of longint; 2 q,a,size,fa:array[0..16000]of longint; 3 hash:array[0..40,0..40,0..40,0..40]of longint; 4 dp:array[0..600,0..16000]of longint; 5 ch:string; 6 n,cnt,i,j,k,x,t,y,ans,len,s,cas,a1,c1,g1,t1,u,s1,v,s2,num:longint; 7 flag:boolean; 8 9 function min(x,y:longint):longint; 10 begin 11 if x<y then exit(x); 12 exit(y); 13 end; 14 15 function max(x,y:longint):longint; 16 begin 17 if x>y then exit(x); 18 exit(y); 19 end; 20 21 procedure build; 22 var i,u:longint; 23 begin 24 u:=1; 25 for i:=1 to len do 26 begin 27 if map[u,a[i]]=0 then 28 begin 29 inc(cnt); map[u,a[i]]:=cnt; 30 end; 31 u:=map[u,a[i]]; 32 end; 33 inc(size[u]); 34 end; 35 36 procedure acauto; 37 var t,w,i,p,son,u:longint; 38 begin 39 t:=0; w:=1; q[1]:=1; 40 while t<w do 41 begin 42 inc(t); u:=q[t]; 43 size[u]:=size[u]+size[fa[u]]; 44 for i:=1 to 4 do 45 if map[u,i]>0 then 46 begin 47 son:=map[u,i]; 48 p:=fa[u]; 49 if u=1 then fa[son]:=1 50 else fa[son]:=map[p,i]; 51 inc(w); q[w]:=son; 52 end 53 else 54 begin 55 p:=fa[u]; 56 if u=1 then map[u,i]:=1 57 else map[u,i]:=map[p,i]; 58 end; 59 end; 60 end; 61 62 begin 63 assign(input,‘hdoj3341.in‘); reset(input); 64 assign(output,‘hdoj3341.out‘); rewrite(output); 65 while not eof do 66 begin 67 readln(n); 68 if n=0 then break; 69 inc(cas); 70 for i:=1 to cnt do 71 begin 72 size[i]:=0; fa[i]:=0; 73 end; 74 for i:=1 to cnt do 75 for j:=1 to 4 do map[i,j]:=0; 76 for i:=0 to a1 do 77 for j:=0 to c1 do 78 for k:=0 to g1 do 79 for x:=0 to t1 do hash[i,j,k,x]:=0; 80 81 cnt:=1; 82 for i:=1 to n do 83 begin 84 readln(ch); 85 len:=length(ch); 86 for j:=1 to len do 87 begin 88 case ch[j] of 89 ‘A‘:a[j]:=1; 90 ‘C‘:a[j]:=2; 91 ‘G‘:a[j]:=3; 92 ‘T‘:a[j]:=4; 93 end; 94 end; 95 build; 96 end; 97 acauto; 98 readln(ch); 99 len:=length(ch); a1:=0; c1:=0; g1:=0; t1:=0; 100 for i:=1 to len do 101 begin 102 case ch[i] of 103 ‘A‘:inc(a1); 104 ‘C‘:inc(c1); 105 ‘G‘:inc(g1); 106 ‘T‘:inc(t1); 107 end; 108 end; 109 num:=0; 110 for i:=0 to a1 do 111 for j:=0 to c1 do 112 for k:=0 to g1 do 113 for x:=0 to t1 do 114 begin 115 inc(num); hash[i,j,k,x]:=num; 116 end; 117 118 for i:=1 to cnt do 119 for j:=0 to a1 do 120 for k:=0 to c1 do 121 for x:=0 to g1 do 122 for y:=0 to t1 do dp[i,hash[j,k,x,y]]:=-1; 123 dp[1,hash[0,0,0,0]]:=0; 124 125 ans:=0; 126 for i:=0 to a1 do 127 for j:=0 to c1 do 128 for k:=0 to g1 do 129 for x:=0 to c1 do 130 begin 131 if i+j+k+x=0 then continue; 132 s1:=hash[i,j,k,x]; 133 for u:=1 to cnt do 134 for t:=1 to 4 do 135 begin 136 v:=map[u,t]; 137 s2:=0; 138 if (t=1)and(i>=1) then s2:=hash[i-1,j,k,x] 139 else if (t=2)and(j>=1) then s2:=hash[i,j-1,k,x] 140 else if (t=3)and(k>=1) then s2:=hash[i,j,k-1,x] 141 else if (t=4)and(x>=1) then s2:=hash[i,j,k,x-1]; 142 if s2=0 then continue; 143 if dp[u,s2]=-1 then continue; 144 dp[v,s1]:=max(dp[v,s1],dp[u,s2]+size[v]); 145 ans:=max(ans,dp[v,s1]); 146 end; 147 end; 148 writeln(‘Case ‘,cas,‘: ‘,ans); 149 end; 150 close(input); 151 close(output); 152 end.
以上是关于HDOJ3341Lost's revenge(AC自动机,DP)的主要内容,如果未能解决你的问题,请参考以下文章
HDU - 3341 Lost's revenge(AC自己主动机+DP)
L - Lost's revenge HDU - 3341 (AC自动机 + 记忆化搜索 + 变进制算法)
HDU3341 Lost's revenge(AC自动机+DP)
Lost's revenge HDU - 3341 AC自动机+DP(需要学会如何优雅的压缩状态)