1. 程式人生 > >【HDOJ3341】Lost's revenge(AC自動機,DP)

【HDOJ3341】Lost's revenge(AC自動機,DP)

res n) trie hdoj 字母 div 其中 func color

題意:給出一個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.

【HDOJ3341】Lost's revenge(AC自動機,DP)