Lost's revenge
#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <vector>#include <queue>#include <algorithm>using namespace std;#define pb push_backstruct node { int son[4],fail; int cnt; node(){cnt=0,fail=0;memset(son,0,sizeof(son));}};vector<node> ac;int dp[510][11*11*11*11];//題目沒說各個字母的數目,只說了總數40,所以四個狀態得這樣放到一維裡int hash[128];void init() { hash['A']=0; hash['T']=1; hash['C']=2; hash['G']=3;}void insert(const char *str) { int p=0,i=0,tmp; while(str[p]) { tmp=hash[str[p]]; if(!ac[i].son[tmp]) { ac[i].son[tmp]=ac.size(); ac.pb(node()); } i=ac[i].son[tmp]; ++p; } ++ac[i].cnt;}void getFail() { queue<int> qu; qu.push(0); while(!qu.empty()) { int cur=qu.front();qu.pop(); for(int i=0;i<4;++i) { int p=ac[cur].fail,son=ac[cur].son[i]; if(son) qu.push(son); if(cur) { if(son) ac[son].fail=ac[p].son[i],ac[son].cnt+=ac[ac[p].son[i]].cnt; else ac[cur].son[i]=ac[p].son[i]; } } }}int main() { ios::sync_with_stdio(false); int n,cas=0; init(); while(cin >> n,n) { ac.clear(); ac.pb(node()); char str[45]; while(n--) { cin >> str; insert(str); } int na[4];//各個字母個數 memset(na,0,sizeof(na)); cin >> str; int len=0; for(int i=0;str[i];++i) { ++len; switch(str[i]) { case 'A':++na[0];break; case 'T':++na[1];break; case 'C':++na[2];break; case 'G':++na[3]; } } getFail(); memset(dp,-1,sizeof(dp)); dp[0][0]=0; register int ii[5],p[5]; p[3]=1; p[2]=na[3]+1;//注意這裡要+1,字母的數目為0的情況也要計算 p[1]=(na[2]+1)*(na[3]+1); p[0]=(na[1]+1)*p[1]; int ans=0; int size=ac.size(); for(ii[0]=0;ii[0]<=na[0];++ii[0]) { for(ii[1]=0;ii[1]<=na[1];++ii[1]) { for(ii[2]=0;ii[2]<=na[2];++ii[2]) { for(ii[3]=0;ii[3]<=na[3];++ii[3]) { for(ii[4]=0;ii[4]<size;++ii[4]) { int pp=ii[0]*p[0]+ii[1]*p[1]+ii[2]*p[2]+ii[3]; if(dp[ii[4]][pp]==-1) continue; for(int k=0;k<4;++k) { int son=ac[ii[4]].son[k]; if(ii[k]==na[k]) continue; int ppp=pp+p[k]; dp[son][ppp]=max(dp[son][ppp],dp[ii[4]][pp]+ac[son].cnt); if(ii[0]+ii[1]+ii[2]+ii[3]+1==len) ans=max(ans,dp[son][ppp]); } } } } } } cout << "Case " << ++cas << ": " << ans << endl; } return 0;}