标签:
ac自动机加状压dp加广搜优化
#include<iostream> #include<map> #include<string.h> #include<stdio.h> #include<algorithm> #include<queue> using namespace std; const int maxa = 500; const int cha = 4; int n, m, k; int num_[4]; map<char, int> mp; /*struct point{ short a[4]; bool operator <(const point& b)const{ if(a[0] != b.a[0]) return a[0] < b.a[0]; else if(a[1] != b.a[1]) return a[1] < b.a[1]; else if(a[2] != b.a[2]) return a[2] < b.a[2]; else return a[3] < b.a[3]; } }; map<point, int>dp[maxa]; map<point, bool> bo;*/ int dp[500][11*11*11*11]; int num[maxa]; struct Tire{ int next[maxa][cha], fail[maxa]; long long end[maxa], po[maxa]; int root, L; int newnode(){ for(int i = 0; i < cha; i++){ next[L][i] = -1; } end[L] = 0; num[L++] = 0; return L-1; } void init(){ L = 0; root = newnode(); } void insert(char buf[], int ii){ int len = strlen(buf); int now = root; for(int i = 0; i < len; i++){ int x = mp[buf[i]]; if(next[now][x] == -1) next[now][x] = newnode(); now = next[now][x]; //printf("%d ", now); }//puts(""); long long one = 1; end[now] |= (one<<ii); } void build(){ queue<int>Q; fail[root] = root; for(int i = 0; i < cha; i++){ if(next[root][i] == -1) next[root][i] = root; else{ fail[next[root][i]] = root; Q.push(next[root][i]); } } while(!Q.empty()){//printf("*"); int now = Q.front(); end[now] |= end[fail[now]]; long long p = end[now]; while(p){ num[now] += p%2; p /= 2; } Q.pop(); // end[now] |= end[fail[now]]; for(int i = 0; i < cha; i++){ if(next[now][i] == -1) next[now][i] = next[fail[now]][i]; else{ fail[next[now][i]] = next[fail[now]][i]; Q.push(next[now][i]); // printf("**%d %d\n",next[now][i],next[fail[ now]][i]); } } } } int solve(){//printf("**%d\n", next[1][3]); memset(dp, -1, sizeof(dp)); dp[0][0] = 0; bool vis[11*11*11*11]; memset(vis, 0, sizeof(vis)); queue<int>que; que.push(0); while(!que.empty()){ int now = que.front(); que.pop(); //printf("%d ", now); int wei = 1; for(int i =0;i < 4; i++){/*if(now==1){printf("&&\n"); printf("%d %d\n", wei, num_[i]); }*/ if(now % (wei*(num_[i]+1)) /wei == num_[i]){ wei *= num_[i] +1; continue; } int Next_state = now+wei; if(!vis[Next_state]){ vis[Next_state] = 1; que.push(Next_state); } for(int k = 0; k < L; k++){ /*if(k == 1 && now == 1){ printf("--%d %d\n", next[k][i],Next_state); }*/ if(dp[k][now] == -1)continue; dp[next[k][i]][Next_state] = max(dp[next[k][i]][Next_state], dp[k][now]+num[next[k][i]]); } wei *= (num_[i]+1); } } int ans = 0; int maxn = 1; for(int i = 0;i < 4; i++){ maxn *= num_[i]+1; } for(int k = 0; k < maxn; k++){ for(int i = 0; i < L; i++){//printf("%d %d %d\n", i, k, dp[i][k]); ans = max(ans, dp[i][k]); } }return ans; } }; char buf[45]; Tire ac; int main(){ //freopen("in.cpp","r", stdin); mp[‘A‘] = 0; mp[‘T‘] = 1; mp[‘G‘] = 2; mp[‘C‘] = 3; int n; int Case = 1; while(scanf("%d", &n), n != 0){ memset(num_, 0, sizeof(num_)); ac.init(); for(int i = 0; i < n; i++){ scanf("%s", buf); ac.insert(buf, i); } scanf("%s", buf); memset(num, 0, sizeof(num)); for(int i = 0; buf[i]; i++){ num_[mp[buf[i]]] ++; } ac.build(); printf("Case %d: %d\n", Case ++, ac.solve()); } } /* abcdefg bcdefg cdef de e ssaabcdefg */
标签:
原文地址:http://www.cnblogs.com/icodefive/p/4395710.html