HDU 3247 Resource Archiver (AC自己主动机 + BFS + 状态压缩DP)
题目链接:Resource Archiver
解析:n个正常的串。m个病毒串,问包括全部正常串(可重叠)且不包括不论什么病毒串的字符串的最小长度为多少。
AC自己主动机 + bfs + 状态压缩DP
用最短路预处理出状态的转移。能够优化非常多
AC代码:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std; const int INF = 0x3f3f3f3f;
struct Trie{
int next[60010][2], fail[60010], end[60010];
int root, L;
int newnode(){
for(int i=0; i<2; i++) next[L][i] = -1;
end[L++] = 0;
return L-1;
}
void init(){
L = 0;
root = newnode();
}
void insert(char buf[], int id){
int len = strlen(buf);
int now = root;
for(int i=0; i<len; i++){
if(next[now][buf[i] - '0'] == -1)
next[now][buf[i] - '0'] = newnode();
now = next[now][buf[i] - '0'];
}
end[now] = id;
}
void build(){
queue<int> Q;
fail[root] = root;
for(int i=0; i<2; i++)
if(next[root][i] == -1) next[root][i] = root;
else{
fail[ next[root][i] ] = root;
Q.push(next[root][i]);
}
while(!Q.empty()){
int now = Q.front();
Q.pop();
if(end[ fail[now] ] == -1) end[now] = -1;
else end[now] |= end[ fail[now] ];
for(int i=0; i<2; 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]);
}
}
}
int g[11][11];
int dp[1025][11];
int cnt;
int pos[11];
int dis[60010]; void bfs(int k){
queue<int> q;
memset(dis, -1, sizeof(dis));
dis[pos[k]] = 0;
q.push(pos[k]);
while(!q.empty()){
int now = q.front();
q.pop();
for(int i=0; i<2; i++){
int tmp = next[now][i];
if(dis[tmp] < 0 && end[tmp] >= 0){
dis[tmp] = dis[now] + 1;
q.push(tmp);
}
}
}
for(int i=0; i<cnt; i++) g[k][i] = dis[pos[i]];
} int solve(int n){
pos[0] = 0;
cnt = 1;
for(int i=0; i<L; i++)
if(end[i] > 0) pos[cnt++] = i;
for(int i=0; i<cnt; i++) bfs(i); for(int i=0; i<(1<<n); i++)
for(int j=0; j<cnt; j++)
dp[i][j] = INF;
dp[0][0] = 0;
for(int i=0; i<(1<<n); i++)
for(int j=0; j<cnt; j++)
if(dp[i][j] < INF){
for(int k=0; k<cnt; k++){
if(g[j][k] < 0) continue;
if(j == k) continue;
dp[i | end[pos[k]]][k] = min(dp[i | end[pos[k]]][k], dp[i][j] + g[j][k]);
}
}
int ans = INF;
for(int i=0; i<cnt; i++)
ans = min(ans, dp[(1<<n)-1][i]);
return ans;
}
}; char buf[1010];
Trie ac; int main(){
#ifdef sxk
freopen("in.txt", "r", stdin);
#endif // sxk
int n, m;
while(scanf("%d%d", &n, &m) == 2){
if(n == 0 && m == 0) break;
ac.init();
for(int i=0; i<n; i++){
scanf("%s", buf);
ac.insert(buf, 1<<i);
}
for(int i=0; i<m; i++){
scanf("%s", buf);
ac.insert(buf, -1);
}
ac.build();
printf("%d\n", ac.solve(n));
}
return 0;
}
HDU 3247 Resource Archiver (AC自己主动机 + BFS + 状态压缩DP)的更多相关文章
- HDU 3247 Resource Archiver (AC自动机+BFS+状压DP)
题意:给定 n 个文本串,m个病毒串,文本串重叠部分可以合并,但合并后不能含有病毒串,问所有文本串合并后最短多长. 析:先把所有的文本串和病毒都插入到AC自动机上,不过标记不一样,可以给病毒标记-1, ...
- HDU - 3247 Resource Archiver (AC自动机,状压dp)
\(\quad\)Great! Your new software is almost finished! The only thing left to do is archiving all you ...
- POJ 3691 & HDU 2457 DNA repair (AC自己主动机,DP)
http://poj.org/problem?id=3691 http://acm.hdu.edu.cn/showproblem.php?pid=2457 DNA repair Time Limit: ...
- HDU 2825 Wireless Password (AC自己主动机,DP)
pid=2825">http://acm.hdu.edu.cn/showproblem.php? pid=2825 Wireless Password Time Limit: 2000 ...
- HDU 2896 病毒侵袭 (AC自己主动机)
pid=2896">http://acm.hdu.edu.cn/showproblem.php?pid=2896 病毒侵袭 Time Limit: 2000/1000 MS (Java ...
- hdu 2222 Keywords Search ac自己主动机
点击打开链接题目链接 Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Ja ...
- HDU 2896 病毒侵袭 AC自己主动机题解
本题是在text里面查找key word的增强版.由于这里有多个text. 那么就不能够简单把Trie的叶子标志记录改动成-1进行加速了,能够使用其它技术.我直接使用个vis数组记录已经訪问过的节点, ...
- HDU - 2825 Wireless Password(AC自己主动机+DP)
Description Liyuan lives in a old apartment. One day, he suddenly found that there was a wireless ne ...
- HDU 2222 Keywords Search AC自己主动机入门题
单词统计的题目,给出一些单词,统计有多少单词在一个文本中出现,最经典的入门题了. AC自己主动机的基础: 1 Trie. 以这个数据结构为基础的,只是添加一个fail指针和构造fail的函数 2 KM ...
随机推荐
- jmeter关联、下载文件、简单压测
关联 一.什么是关联 关联是请求与请求之间存在数据依赖关系,需要从上一个请求获取下一个请求需要回传回去的数据. 简单地说就是在测试过程中有些数据的值会经常发生变化,要获取并使用这些数据,把这个动态的信 ...
- JavaScript--Array 数组对象
Array 数组对象 数组对象是一个对象的集合,里边的对象可以是不同类型的.数组的每一个成员对象都有一个“下标”,用来表示它在数组中的位置,是从零开始的 数组定义的方法: 1. 定义了一个空数组: v ...
- 【LeetCode】-- 260. Single Number III
问题描述: https://leetcode.com/problems/single-number-iii/ 在一个数组里面,只有两个元素仅出现过1次,其余都出现过两次.找出出现仅一次的那两个(a, ...
- 【转】Linux命令学习手册-split命令
转自:http://blog.chinaunix.net/uid-9525959-id-3054325.html split [OPTION] [INPUT [PREFIX]] [功能]将文件分割成多 ...
- [转]android 获取 imei号码
核心代码: Imei = ((TelephonyManager) getSystemService(TELEPHONY_SERVICE)) .getDeviceId(); 1.加入权限 在manife ...
- Dancing Links X 学习笔记
\(\\\) Definitions 双向链表:记录前后两个指针的链表,每个顺序关系都有双向的指针维护. \(Dancing\ Links\):双向十字循环链表,建立在二维关系上,每个元素记录上下左右 ...
- js 学习笔记---BOM
window对象 1. window 对象是Global对象,在全局作用域中声明的变量和函数都可以通过window.来访问.跟直接在window上添加属性效果一样.唯一的区别就是delete时,如果是 ...
- SQLServer 异常捕获,回滚,再抛出
一个存储过程中多个更新操作,后面的更新操作出现异常,如果不手动回滚前面修改的数据是不会自动撤销的! BEGIN TRY BEGIN TRAN -- ..... COMMIT TRAN END TRY ...
- 用Grunt进行CSS文件压缩
假设你的项目的CSS文件全部放在项目目录下名为css的文件夹中,现在将它压缩合并成一个名为main-min.css的文件,放在css-min文件夹下. (1)首先保证机器安装了node.js. (2) ...
- HDU_1068_Girls and Boys_二分图匹配
Girls and Boys Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...