hdu 4057 AC自动机
题目链接http://acm.hdu.edu.cn/showproblem.php?pid=4057
自动机上的dp
/*
hdu 4057
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <vector>
#include <bitset>
#include <stack>
#include <queue>
#include <map>
#include <algorithm>
#include <iostream>
#include <string>
#include <set>
#define X first
#define Y second
#define sqr(x) (x)*(x)
#pragma comment(linker,"/STACK:102400000,102400000")
using namespace std;
const double PI = acos(-1.0);
map<int, int>::iterator it;
typedef long long LL ;
template<typename T> void checkmin(T &x, T y) {x = min(x, y);}
template<typename T> void checkmax(T &x, T y) {x = max(x, y);}
const int MAX_NODE = 1005;
const int CHILD_NUM = 4;
const int inf = 1e6;
int dp[2][MAX_NODE][1<<10];
int n, L;
int w[11];
class ACAutomaton {
public:
int chd[MAX_NODE][CHILD_NUM];
int fail[MAX_NODE];
int Q[MAX_NODE];
int val[MAX_NODE];
int ID[256];
int sz;
void Init() {
ID['A'] = 0;
ID['G'] = 1;
ID['T'] = 2;
ID['C'] = 3;
}
void Reset() {
fail[0] = 0;
memset(chd[0], 0, sizeof(chd[0]));
sz = 1;
}
void Insert(char *s, int k) {
int q = 0;
for(; *s; ++s) {
int c = ID[*s];
if(!chd[q][c]) {
memset(chd[sz], 0, sizeof(chd[sz]));
val[sz] = 0;
chd[q][c] = sz++;
}
q = chd[q][c];
}
val[q] |= 1 << k;
}
void Construct() {
int *s = Q, *e = Q;
for(int i = 0; i < CHILD_NUM; ++i) {
if(chd[0][i]) {
*e++ = chd[0][i];
fail[ chd[0][i] ] = 0;
}
}
while(s != e) {
int r = *s++;
for(int i = 0; i < CHILD_NUM; ++i) {
int &u = chd[r][i];
int v = fail[r];
if(u) {
*e++ = u;
fail[u] = chd[v][i];
val[u] |= val[ fail[u] ];
}
else u = chd[v][i];
}
}
}
int Get_dp() {
int st = 0, ed = 1;
for(int i = 0; i < sz; ++i)for(int j = 0; j < (1 << n); ++j)dp[st][i][j]=dp[ed][i][j] = -inf;
dp[0][0][0] = 0;
for(int i = 0; i < L; ++i) {
for(int j = 0; j < sz; ++j) {
for(int mask = 0; mask < (1 << n); ++mask) {
if(dp[st][j][mask] > -inf) {
for(int k = 0; k < CHILD_NUM; ++k) {
int q = chd[j][k];
int qmask = val[q];
int pmask = (qmask ^ mask)&qmask;
int add = 0;
for(int p = 0; p < n; ++p) {
if((pmask >> p) & 1) {
add += w[p];
}
}
checkmax(dp[ed][q][pmask|mask], dp[st][j][mask] + add);
}
}
}
}
for(int j = 0; j < sz; ++j)for(int k = 0; k < (1 << n); ++k)dp[st][j][k] = -inf;
st ^= 1, ed ^= 1;
}
int res = -inf;
for(int i = 0; i < sz; ++i) {
for(int j = 0; j < (1 << n); ++j) {
res = max(res, dp[st][i][j]);
}
}
return res;
}
} AC;
char s[105];
int main() {
AC.Init();
while(~scanf("%d%d", &n, &L)) {
AC.Reset();
for(int i = 0; i < n; ++i) {
scanf("%s %d", s, w + i);
AC.Insert(s, i);
}
AC.Construct();
int res = AC.Get_dp();
if(res < 0) {
puts("No Rabbit after 2012!");
}
else {
printf("%d\n", res);
}
}
return 0;
}

浙公网安备 33010602011771号