The shortest sequence that contains all n DNA fragments and does not contain any one of the virus fragments.
It is easy to build an AC automaton with all the DNA fragments and virus fragments, and when the fail is constructed, the node suffix is a DNA or a virus, then dp[s][u] indicates that the set containing the DNA fragment is s and the suffix state is the shortest sequence length of the first U node of the automaton, Then follow the AC automaton to avoid the virus string transfer.
However, the built AC automaton node limit of about 60000, the collection has 1024 states, so that memory is not open. See the puzzle, it is not necessary to consider the automatic machine all the nodes--
- Dp[s][u] represents the shortest sequence length of a DNA fragment containing a set of fragments of a fragment that is S and the suffix is the first u
- By using BFS to preprocess the distance from each DNA fragment to other DNA fragments on an AC automaton, be aware that some fragments of DNA have suffixes that contain other fragments of DNA, and that the jump suffix contains the nodes of the virus string.
- Transfer is Dp[s][u]=max (Dp[s-{u}][v]+dist[v][u]) (V∈s-{u})
I have to digest the correctness of this solution.
1#include <cstdio>2#include <cstring>3#include <queue>4#include <algorithm>5 using namespacestd;6 #defineINF (1<<29)7 #defineMAXN 666668 inttn,ch[maxn][2],FAIL[MAXN],FLAG[MAXN];9 intidx[ One]; Ten voidInsertChar*s,intk) { One intx=0; A for(intI=0; T[n]; ++i) { - inty=s[i]-'0'; - if(ch[x][y]==0) ch[x][y]=++tn; thex=Ch[x][y]; - } - if(k==-1|| flag[x]==-1) flag[x]=-1; - Else{ +idx[k]=x; -Flag[x]|= (1<<k); + } A } at intque[maxn],front,rear; - voidGetfail () { -memset (fail,0,sizeof(fail)); -Front=rear=0; - if(ch[0][0]) que[rear++]=ch[0][0]; - if(ch[0][1]) que[rear++]=ch[0][1]; in while(front<rear) { - intx=que[front++]; to for(intI=0; i<2; ++i) { + if(Ch[x][i]) { -que[rear++]=Ch[x][i]; thefail[ch[x][i]]=Ch[fail[x]][i]; * if(flag[ch[x][i]]==-1|| flag[ch[fail[x]][i]]==-1) flag[ch[x][i]]=-1; $ Elseflag[ch[x][i]]|=Flag[ch[fail[x]][i]];Panax Notoginseng}Elsech[x][i]=Ch[fail[x]][i]; - } the } + } A the intn,m,dist[maxn],g[ One][ One]; + voidBFS (intk) { -memset (Dist,0,sizeof(Dist)); $dist[idx[k]]=1; $Front=rear=0; -que[rear++]=Idx[k]; - while(front<rear) { the intx=que[front++]; - if(Flag[x]) {Wuyi for(intI=0; i<n; ++i) { the if((flag[x]>>i) &1)==0)Continue; -G[k][i]=min (g[k][i],dist[x]-1); Wu } - } About for(intI=0; i<2; ++i) { $ inty=Ch[x][i]; - if(flag[y]==-1|| Dist[y])Continue; -dist[y]=dist[x]+1; -que[rear++]=y; A } + } the } - intd[1<<Ten][ One],len[ One]; $ intMain () { the Charstr[1111]; the while(~SCANF ("%d%d", &n,&m) && (n| |m)) { thetn=0; thememset (CH,0,sizeof(CH)); -memset (Flag,0,sizeof(flag)); in for(intI=0; i<n; ++i) { thescanf"%s", str); the Insert (str,i); Aboutlen[i]=strlen (str); the } the for(intI=0; i<m; ++i) { thescanf"%s", str); +Insert (str,-1); - } the Getfail ();Bayi for(intI=0; i<n; ++i) { the for(intj=0; j<n; ++J) g[i][j]=INF; the } - for(intI=0; i<n; ++i) { - BFS (i); the } the for(intI=0; i< (1<<N); ++i) { the for(intj=0; j<n; ++J) d[i][j]=INF; the } - for(intI=0; i<n; ++i) { thed[1<<i][i]=Len[i]; the } the for(intI=1; i< (1<<N); ++i) {94 for(intj=0; j<n; ++j) { the if((I>>J) &1)==0)Continue; the for(intk=0; k<n; ++k) { the if((i>>k) &1)==0|| J==K)Continue;98D[i][j]=min (d[i][j],d[i^ (1<<J)][k]+g[k][j]); About } - }101 }102 intres=INF;103 for(intI=0; i<n; ++i) Res=min (res,d[(1<<n)-1][i]);104printf"%d\n", res); the }106 return 0;107}
HDU3247 Resource archiver (ac automaton +BFS+DP)