自动机上状压dp,把单词是否存在压成二进制位
注意这里面某些单词会包含其他单词,所以某些自动机上有些状态点对应多个二进制位
方案只要再顺着有方案的状态搜一遍即可
1 var trie,go:array[0..110,'a'..'z'] of longint; 2 f,q,v:array[0..110] of longint; 3 ans:array[0..50] of string; 4 dp:array[0..25,0..100,0..1023] of int64; 5 t,k,i,j,n,m,l:longint; 6 c:char; 7 s:string; 8 9 function calc(n:longint):int64; 10 var i:longint; 11 begin 12 calc:=1; 13 for i:=1 to n do 14 calc:=calc*26; 15 end; 16 17 procedure ac; 18 var h,r,x,y,j,i:longint; 19 c:char; 20 begin 21 h:=1; 22 r:=0; 23 for c:='a' to 'z' do 24 if trie[0,c]>0 then 25 begin 26 inc(r); 27 q[r]:=trie[0,c]; 28 end; 29 30 while h<=r do 31 begin 32 x:=q[h]; 33 for c:='a' to 'z' do 34 if trie[x,c]>0 then 35 begin 36 y:=trie[x,c]; 37 inc(r); 38 q[r]:=y; 39 j:=f[x]; 40 while (j>0) and (trie[j,c]=0) do j:=f[j]; 41 f[y]:=trie[j,c]; 42 v[y]:=v[y] or v[trie[j,c]]; 43 end; 44 inc(h); 45 end; 46 end; 47 48 function dfs(i,p,q:longint):int64; 49 var c:char; 50 begin 51 if i=m then 52 begin 53 if q=1 shl n-1 then dp[i,p,q]:=1 54 else dp[i,p,q]:=0; 55 end; 56 if dp[i,p,q]<>-1 then exit(dp[i,p,q]); 57 if (q=1 shl n-1) and (m-i<2) then exit(calc(m-i)); 58 dp[i,p,q]:=0; 59 for c:='a' to 'z' do 60 dp[i,p,q]:=dp[i,p,q]+dfs(i+1,go[p,c],q or v[go[p,c]]); 61 exit(dp[i,p,q]); 62 end; 63 64 procedure get(i,p,q:longint); 65 var c:char; 66 j:longint; 67 begin 68 if i=m then 69 begin 70 inc(t); 71 ans[t]:=s; 72 end 73 else begin 74 for c:='a' to 'z' do 75 if dp[i+1,go[p,c],q or v[go[p,c]]]>0 then 76 begin 77 s[i+1]:=c; 78 get(i+1,go[p,c],q or v[go[p,c]]); 79 end; 80 end; 81 end; 82 83 begin 84 readln(m,n); 85 for i:=1 to n do 86 begin 87 j:=0; 88 readln(s); 89 l:=length(s); 90 for k:=1 to l do 91 begin 92 if trie[j,s[k]]=0 then 93 begin 94 inc(t); 95 trie[j,s[k]]:=t; 96 end; 97 j:=trie[j,s[k]]; 98 end; 99 v[j]:=1 shl (i-1); 100 end; 101 ac; 102 for i:=0 to t do 103 for c:='a' to 'z' do 104 begin 105 j:=i; 106 while (j>0) and (trie[j,c]=0) do j:=f[j]; 107 go[i,c]:=trie[j,c]; 108 end; 109 110 fillchar(dp,sizeof(dp),255); 111 writeln(dfs(0,0,0)); 112 if dp[0,0,0]<=42 then 113 begin 114 t:=0; 115 s:=''; 116 for i:=1 to m do 117 s:=s+' '; 118 get(0,0,0); 119 for i:=1 to t do 120 writeln(ans[i]); 121 end; 122 end.