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的更多相关文章
随机推荐
- knockout-validation不自动插入错误消息
<div data-bind="validationOptions:{insertMessages:false}"> <div class="valid ...
- ASP.NET MVC使用Bootstrap系统(2)——使用Bootstrap CSS和HTML元素
阅读目录 Bootstrap 栅格(Grid)系统 Bootstrap HTML元素 Bootstrap 验证样式 ASP.NET MVC创建包含Bootstrap样式编辑模板 小结 Bootstra ...
- 删除多个Safari书签
Safari 的书签多了,删除起来很麻烦,可以先选中所有书签,然后再按"Command+Delete",就可以全部删除了.
- 给各位聚聚和大大介绍一个开源项目 Expression2Sql(转)
阅读目录 一.Expression2Sql介绍 二.单表简单查询 三.Where条件 四.多表关联查询 五.group by 六.order by 七.函数 八.delete 删除 九.update ...
- 优化PHP程序的方法(温故知新)
1. If a method c++an be static, declare it static. Speed improvement is by a factor of 4. 如果一个方法可静态化 ...
- 继承IDbConnection连接不同数据库
继承IDbConnection连接不同数据库 本方案可实现仅修改app.config即可连接不同数据库,但是设计数据库时需要注意各种数据库的数据类型是不一样的. 各种不同数据库的Connection. ...
- OC第四节——NSDictionary和NSMutableDictionary
NSDictionary 1.什么是字典 字典是也是一种集合结构,功能与我们现实中的字典工具一样 2.字典的元素是什么 任意类型的对象地址构成键值对 3. ...
- CF #305 (Div. 2) C. Mike and Frog(扩展欧几里得&&当然暴力is also no problem)
C. Mike and Frog time limit per test 1 second memory limit per test 256 megabytes input standard inp ...
- 大数据处理时用到maven的repository
由于做数据处理时,经常遇到maven 下载依赖包错误,下面我将自己下载好的repository 分享下 里边包含:Hadoop ,storm ,sprk ,kafka ,等 压缩后500多M. htt ...
- 【Go入门教程8】总结(25个关键字)
这一章我们主要介绍了Go语言的一些语法,通过语法我们可以发现Go是多么的简单,只有二十五个关键字.让我们再来回顾一下这些关键字都是用来干什么的. break default func ...