您的位置:首页 > 其它

HDU 4534 郑厂长系列故事——新闻净化

2013-04-01 15:34 218 查看
  跟 HDU 4057 Rescue the Rabbit差不多的AC自动机+dp,比赛的时候被虐成傻逼了!!!

999的状态不多,直接状态压缩就行。dp[i][ACstatus][status] 到字符串第i位置,在AC自动机上状态为ACstatus,包含到999的状态为status。

更新了一下自动机的模板。。。Orz简洁写法

View Code

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>

#define CL(arr, val)    memset(arr, val, sizeof(arr))
#define REP(i, n)       for((i) = 0; (i) < (n); ++(i))
#define FOR(i, l, h)    for((i) = (l); (i) <= (h); ++(i))
#define FORD(i, h, l)   for((i) = (h); (i) >= (l); --(i))
#define L(x)    (x) << 1
#define R(x)    (x) << 1 | 1
#define MID(l, r)   (l + r) >> 1
#define Min(x, y)   (x) < (y) ? (x) : (y)
#define Max(x, y)   (x) < (y) ? (y) : (x)
#define E(x)        (1 << (x))
#define iabs(x)     (x) < 0 ? -(x) : (x)
#define OUT(x)  printf("%lld\n", x)
#define Read()  freopen("data.in", "r", stdin)
#define Write() freopen("data.out", "w", stdout);

typedef long long LL;
const double eps = 1e-6;
const double PI = acos(-1.0);
const int inf = 0x1F1F1F1F;

using namespace std;

const int N = 1610;

struct node {
int val;
short type;
bool cannot;
short index;
node *pre, *next[26];
void init() {
val = type = 0;
index = cannot = 0;
pre = NULL;
memset(next, 0, sizeof(next));
}
};

node trie
;
node *root, *q
;

int cnt, must;
int dp[2]
[1<<8];
int vv[2]
[1<<8];
char str[110];

void insert(node* root, char* str, int val) {
int c, i;
for(i = 0; str[i] != 0; ++i) {
c = str[i] - 'a';
if(root->next[c] == 0) {
root->next[c] = &trie[++cnt];
root->next[c]->init();
root->next[c]->index = cnt;
}
root = root->next[c];
}
if(val == 999) {
root->type |= (1<<must++);
} else if(val == -999) {
root->cannot = 1;
} else {
root->val += val;
}
}

void buildAC() {
int head, tail, i;
node *u;
root->pre = root;

head = tail = 0;
q[tail++] = root;

while(head < tail) {
u = q[head++];

u->val += u->pre->val;
u->type |= u->pre->type;
u->cannot |= u->pre->cannot;

for(i = 0; i < 26; ++i) {
if(u->next[i] == 0) {
if(u == root)   u->next[i] = root;
else    u->next[i] = u->pre->next[i];
} else {
if(u == root)   u->next[i]->pre = root;
else    u->next[i]->pre = u->pre->next[i];

/*
if(u->next[i]->pre->val)    u->next[i]->val += u->next[i]->pre->val;
if(u->next[i]->pre->type)   u->next[i]->type |= u->next[i]->pre->type;
if(u->next[i]->pre->cannot) u->next[i]->cannot = 1;
*/

q[tail++] = u->next[i];
}
}
}
}

void solve() {
int i, j, k, c;
int nxt, val, tt, n = strlen(str);

CL(dp[1], 0x1f);
CL(vv[1], 0);
dp[1][0][0] = 0;
vv[1][0][0] = 0;

for(i = 0; i < n; ++i) {
CL(dp[i&1], 0x1f);
CL(vv[i&1], 0);
for(j = 0; j <= cnt; ++j) {
for(k = 0; k < (1<<must); ++k) {

if(dp[(i+1)&1][j][k] >= inf)    continue;

if(dp[i&1][j][k] > dp[(i+1)&1][j][k] + 1) {
dp[i&1][j][k] = dp[(i+1)&1][j][k] + 1;
vv[i&1][j][k] = vv[(i+1)&1][j][k];
} else if(dp[i&1][j][k] == dp[(i+1)&1][j][k] + 1 && vv[i&1][j][k] < vv[(i+1)&1][j][k]) {
vv[i&1][j][k] = vv[(i+1)&1][j][k];
}

c = str[i] - 'a';
nxt = trie[j].next[c]->index;
if(trie[nxt].cannot)    continue;

val = trie[nxt].val;
tt = k|trie[nxt].type;

if(dp[i&1][nxt][tt] > dp[(i+1)&1][j][k]) {
dp[i&1][nxt][tt] = dp[(i+1)&1][j][k];
vv[i&1][nxt][tt] = vv[(i+1)&1][j][k] + val;
} else if( dp[i&1][nxt][tt] == dp[(i+1)&1][j][k] &&
vv[i&1][nxt][tt] < vv[(i+1)&1][j][k] + val) {
vv[i&1][nxt][tt] = vv[(i+1)&1][j][k] + val;
}
}
}
}
int ans1 = inf, ans2 = 0, full = (1<<must) - 1;
for(j = 0; j <= cnt; ++j) {
if(ans1 > dp[(n-1)&1][j][full]) {
ans1 = dp[(n-1)&1][j][full];
ans2 = vv[(n-1)&1][j][full];
}
if(ans1 == dp[(n-1)&1][j][full] && ans2 < vv[(n-1)&1][j][full]) {
ans2 = vv[(n-1)&1][j][full];
}
}
if(ans1 == inf)     puts("Banned");
else    printf("%d %d\n", ans1, ans2);
}

int main() {
//freopen("data.in", "r", stdin);

int T, n, g, cas = 0;
scanf("%d", &T);
while(T--) {
root = &trie[0];
root->init();
cnt = must = 0;
scanf("%d", &n);
while(n--) {
scanf("%s %d", str, &g);
insert(root, str, g);
}
buildAC();
scanf("%s", str);
printf("Case %d: ", ++cas);
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: