zju3545
AC自动机+状态压缩DP
注意:相同的串可能出现多次,如果匹配成功则将各次权值加和。
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std; #define D(x) const int MAX_N = ;
const int MAX_LEN = ;
const int MAX_CHILD_NUM = ;
const int MAX_NODE_NUM = MAX_LEN * MAX_N; //1.init() 2.insert() 3.build() 4.query()
struct Trie
{
int next[MAX_NODE_NUM][MAX_CHILD_NUM];
int fail[MAX_NODE_NUM];
int count[MAX_NODE_NUM];
int node_cnt;
bool vis[MAX_NODE_NUM]; //set it to false
int root; void init()
{
node_cnt = ;
root = newnode();
memset(vis, , sizeof(vis));
} int newnode()
{
for (int i = ; i < MAX_CHILD_NUM; i++)
next[node_cnt][i] = -;
count[node_cnt++] = ;
return node_cnt - ;
} int get_id(char a)
{
if (a == 'A')
return ;
if (a == 'T')
return ;
if (a == 'C')
return ;
return ;
} void insert(char buf[], int id)
{
int now = root;
for (int i = ; buf[i]; i++)
{
int id = get_id(buf[i]);
if (next[now][id] == -)
next[now][id] = newnode();
now = next[now][id];
}
count[now] |= ( << id);
} void build()
{
queue<int>Q;
fail[root] = root;
for (int i = ; i < MAX_CHILD_NUM; i++)
if (next[root][i] == -)
next[root][i] = root;
else
{
fail[next[root][i]] = root;
Q.push(next[root][i]);
}
while (!Q.empty())
{
int now = Q.front();
Q.pop();
for (int i = ; i < MAX_CHILD_NUM; i++)
if (next[now][i] == -)
next[now][i] = next[fail[now]][i];
else
{
fail[next[now][i]]=next[fail[now]][i];
count[next[now][i]] |= count[fail[next[now][i]]];
Q.push(next[now][i]);
}
}
} int query(char buf[])
{
int now = root;
int res = ; memset(vis, , sizeof(vis));
for (int i = ; buf[i]; i++)
{
now = next[now][get_id(buf[i])];
int temp = now;
while (temp != root && !vis[temp])
{
res += count[temp];
// optimization: prevent from searching this fail chain again.
//also prevent matching again.
vis[temp] = true;
temp = fail[temp];
}
}
return res;
} void debug()
{
for(int i = ;i < node_cnt;i++)
{
printf("id = %3d,fail = %3d,end = %3d,chi = [",i,fail[i],count[i]);
for(int j = ;j < MAX_CHILD_NUM;j++)
printf("%2d",next[i][j]);
printf("]\n");
}
}
}ac; const int MAX_STATUS = ( << ) + ; int n, len;
char st[MAX_LEN];
int w[MAX_N];
bool dp[][MAX_NODE_NUM][MAX_STATUS]; int cal(int status)
{
int ret = ;
for (int i = ; i < n; i++)
{
if (status & ( << i))
ret += w[i];
}
return ret;
} int work()
{
int ret = -;
memset(dp, , sizeof(dp));
dp[][ac.root][] = true;
for (int i = ; i < len; i++)
{
for (int j = ; j < ac.node_cnt; j++)
for (int status = ; status < ( << n); status++)
dp[(i + ) & ][j][status] = false;
D(printf("%d\n", dp[(i + ) & ][][]));
for (int j = ; j < ac.node_cnt; j++)
{
for (int status = ; status < ( << n); status++)
{
if (!dp[i & ][j][status])
continue;
for (int k = ; k < ; k++)
{
int v = ac.next[j][k];
dp[(i + ) & ][v][status | ac.count[v]] = true;
D(printf("%d %d\n", j, status));
D(printf("%d %d %d %d\n", (i + ) & , v, status | ac.count[v], dp[(i + ) & ][][]));
}
}
}
}
for (int i = ; i < ac.node_cnt; i++)
for (int status = ; status < ( << n); status++)
{
if (dp[len & ][i][status])
{
if (dp[len & ][i][] && status == )
{
D(printf("*%d %d\n", i, ac.count[i]));
}
ret = max(ret, cal(status));
}
}
return ret;
} int main()
{
while (scanf("%d%d", &n, &len) != EOF)
{
ac.init();
for (int i = ; i < n; i++)
{
scanf("%s%d", st, &w[i]);
ac.insert(st, i);
}
ac.build();
int ans = work();
if (ans < )
puts("No Rabbit after 2012!");
else
printf("%d\n", ans);
}
return ;
}
zju3545的更多相关文章
随机推荐
- 是时候放弃Uploadify了
1.Uploadify是什么? Uploadify是来自国外的一款优秀jQuery插件,主要功能是批量上传文件. 这话是复制百度百科的,是:基于jQuery开发的文件上传插件. 2.为什么大家都在用? ...
- [MongoDB]count,gourp,distinct
摘要 上篇文章介绍了CRUD的操作,会了这些,基本上可以完成很多工作了.但如果遇到统计类的操作,那么就需要学习下本篇的内容了. 相关文章 [MongoDB]入门操作 [MongoDB]增删改查 cou ...
- char,short ,int ,long,long long,unsigned long long数据范围
from:http://www.cnblogs.com/A123456A/archive/2013/01/25/2876634.html char,short ,int ,long,long long ...
- 自定义select控件开发
目的:select下拉框条目太多(上百),当用户选择具体项时会浪费用户很多时间去寻找,因此需要一个搜索框让用户输入关键字来匹配列表,便于用户选择 示例图: 1.html结构 <div class ...
- 移动WebApp利用Chrome浏览器进行调试
详细的请看这个(HBuilder是我长期使用,而且值得支持的国内前端开发编辑器) http://ask.dcloud.net.cn/article/151 http://ask.dcloud.net. ...
- 利用CSS实现带相同间隔地无缝滚动动画
说明:因为在移动上主要利用CSS来做动画,所以没有考虑其他浏览器的兼容性,只有-webkit这个前缀,如果需要其他浏览器,请自行补齐. 首先解释一下什么是无缝滚动动画, 例如下面的例子 See the ...
- 透过统计力学,模拟软物质——EPJE专访2016年玻尔兹曼奖得主Daan Frenkel
原文来源:Eur. Phys. J. E (2016) 39: 68 2016年玻尔兹曼奖得主Daan Frenkel接受欧洲物理学报E专访,畅谈统计物理在交叉科学研究中的前所未有的重要性. 统计物理 ...
- Stm32 debug停留在"BKPT 0xAB"或者"SWI 0xAB"的解决办法。
一..背景: 曾经在工作中接触过STM32一段时间,但没有深入的去学习,只是用前辈搭建好的模型来实现一些功能罢了,俗话说的好,大树底下好乘凉,开发确实轻松了,可是不深究点,又觉着心里不踏实,然而也一直 ...
- Android 实现简单音乐播放器(二)
在Android 实现简单音乐播放器(一)中,我介绍了MusicPlayer的页面设计. 现在,我简单总结一些功能实现过程中的要点和有趣的细节,结合MainActivity.java代码进行说明(写出 ...
- 请求WebMethod, Ajax 处理更加专注
在WebForm下 开发ajax程序,需要借助于一般处理程序(*.ashx)或web服务(*.asmx),并且每一个ajax请求,都要建一个这样的文件,如此一来,如 果在一个项目中ajax程序多了,势 ...