HDU3247 Resource Archiver —— AC自动机 + BFS最短路 + 状压DP
题目链接:https://vjudge.net/problem/HDU-3247
Resource Archiver
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 100000/100000 K (Java/Others)
Total Submission(s): 3228 Accepted Submission(s): 1052
Wait a minute… you realized that it isn’t as easy as you thought. Think about the virus killers. They’ll find your software suspicious, if your software contains one of the m predefined virus codes. You absolutely don’t want this to happen.
Technically, resource files and virus codes are merely 01 strings. You’ve already convinced yourself that none of the resource strings contain a virus code, but if you make the archive arbitrarily, virus codes can still be found somewhere.
Here comes your task (formally): design a 01 string that contains all your resources (their occurrences can overlap), but none of the virus codes. To make your software smaller in size, the string should be as short as possible.
1110
0111
101
1001
0 0
题意:
给出n个(n<=10)字符串,和m(m<=1000)个单词。求包含所有字符串,并且不包含任何一个单词的长串的最短长度。
题解:
1.看到n的大小为10,并且要求包含所有字符串,就很容易想到用状压DP。
1.1 设dp[status][u]为:当前状态为status(包含了哪些字符串),并且以字符串u结尾的最短长度。设cost[u][v]为:在字符串u后面接上字符串v所需要的最短长度。由于字符串之间可以有重叠,所以cost[u][v]可能小于len[v];由于长串不能包含单词,所以在链接u、v时,之间可能还需要加一些字符以便跳过单词,所以cost[u][v]可能大于len[v]。
1.2 假如求出了cost数组,那么剩下的就是典型TSP问题了。
2. 如何求cost数组呢?
2.1 把n个字符串和m个单词都插入到AC自动机中,并且需要对字符串和单词作相应的标记。
2.2 对于每个字符串,在自动机上跑最短路,求出当前字符串与其他字符串的最短距离,在跑的时候需要跳过单词。原理:AC自动机各个状态之间的关系构成了一张图。
代码如下:
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- #include <vector>
- #include <cmath>
- #include <queue>
- #include <stack>
- #include <map>
- #include <string>
- #include <set>
- using namespace std;
- typedef long long LL;
- const double EPS = 1e-;
- const int INF = 2e9;
- const LL LNF = 2e18;
- const int MOD = 1e5;
- const int MAXN = 5e4+1e4+;
- int n, m;
- int Index[MAXN], pos[MAXN], cost[][], Len[MAXN];
- int dp[<<][];
- struct Trie
- {
- int sz, base;
- int next[MAXN][], fail[MAXN], end[MAXN];
- int root, L;
- int newnode()
- {
- for(int i = ; i<sz; i++)
- next[L][i] = -;
- end[L++] = false;
- return L-;
- }
- void init(int _sz, int _base)
- {
- sz = _sz;
- base = _base;
- L = ;
- root = newnode();
- }
- int insert(char buf[], bool isVirus)
- {
- int len = strlen(buf);
- int now = root;
- for(int i = ; i<len; i++)
- {
- if(next[now][buf[i]-base] == -) next[now][buf[i]-base] = newnode();
- now = next[now][buf[i]-base];
- }
- end[now] = isVirus;
- return now;
- }
- void build()
- {
- queue<int>Q;
- fail[root] = root;
- for(int i = ; i<sz; 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();
- end[now] |= end[fail[now]];
- for(int i = ; i<sz; i++)
- {
- if(next[now][i] == -) next[now][i] = next[fail[now]][i];
- else fail[next[now][i]] = next[fail[now]][i], Q.push(next[now][i]);
- }
- }
- }
- int query()
- {
- for(int i = ; i<(<<n); i++)
- for(int j = ; j<n; j++)
- dp[i][j] = INF;
- for(int j = ; j<n; j++)
- dp[<<j][j] = Len[j];
- for(int i = ; i<(<<n); i++)
- for(int j = ; j<n; j++)
- {
- if(!(i&(<<j)) || dp[i][j]==INF) continue;
- for(int k = ; k<n; k++)
- if(!(i&(<<k)) && cost[j][k]!=INF)
- dp[i|(<<k)][k] = min(dp[i|(<<k)][k], dp[i][j]+cost[j][k]);
- }
- int ret = INF;
- for(int i = ; i<n; i++)
- ret = min(ret, dp[(<<n)-][i]);
- return ret;
- }
- };
- Trie ac;
- int dis[MAXN];
- void BFS(int st)
- {
- queue<int> Q;
- while(!Q.empty()) Q.pop();
- for(int i = ; i<ac.L; i++)
- dis[i] = INF;
- dis[st] = ;
- Q.push(st);
- while(!Q.empty())
- {
- int u = Q.front(); Q.pop();
- for(int i = ; i<ac.sz; i++)
- {
- int v = ac.next[u][i];
- if(dis[v]==INF && !ac.end[v])
- {
- dis[v] = dis[u] + ;
- Q.push(v);
- }
- }
- }
- for(int i = ; i<n; i++)
- cost[Index[st]][i] = dis[pos[i]];
- }
- char buf[MAXN];
- int main()
- {
- while(scanf("%d%d",&n,&m)&&(n||m))
- {
- ac.init(,'');
- memset(Index, -, sizeof(Index));
- for(int i = ; i<n; i++)
- {
- scanf("%s", buf);
- Len[i] = strlen(buf);
- pos[i] = ac.insert(buf, false);
- Index[pos[i]] = i;
- }
- for(int i = ; i<m; i++)
- {
- scanf("%s", buf);
- ac.insert(buf, true);
- }
- ac.build();
- for(int i = ; i<n; i++)
- BFS(pos[i]);
- int ans = ac.query();
- printf("%d\n", ans);
- }
- }
HDU3247 Resource Archiver —— AC自动机 + BFS最短路 + 状压DP的更多相关文章
- HDU3247 Resource Archiver (AC自动机+spfa+状压DP)
Great! Your new software is almost finished! The only thing left to do is archiving all your n resou ...
- HDU 3247 Resource Archiver (AC自动机+BFS+状压DP)
题意:给定 n 个文本串,m个病毒串,文本串重叠部分可以合并,但合并后不能含有病毒串,问所有文本串合并后最短多长. 析:先把所有的文本串和病毒都插入到AC自动机上,不过标记不一样,可以给病毒标记-1, ...
- hdu3247Resource Archiver (AC自动机+最短路+状压dp)
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 100000/100000 K (Java/Others) Total Submis ...
- HDU 4568 Hunter 最短路+状压DP
题意:给一个n*m的格子,格子中有一些数,如果是正整数则为到此格子的花费,如果为-1表示此格子不可到,现在给k个宝藏的地点(k<=13),求一个人从边界外一点进入整个棋盘,然后拿走所有能拿走的宝 ...
- 最短路+状压DP【洛谷P3489】 [POI2009]WIE-Hexer
P3489 [POI2009]WIE-Hexer 大陆上有n个村庄,m条双向道路,p种怪物,k个铁匠,每个铁匠会居住在一个村庄里,你到了那个村庄后可以让他给你打造剑,每个铁匠打造的剑都可以对付一些特定 ...
- 【BZOJ1097】[POI2007]旅游景点atr 最短路+状压DP
[BZOJ1097][POI2007]旅游景点atr Description FGD想从成都去上海旅游.在旅途中他希望经过一些城市并在那里欣赏风景,品尝风味小吃或者做其他的有趣的事情.经过这些城市的顺 ...
- hdu_3247_Resource Archiver(AC自动机+bfs+TSP)
题目链接:hdu_3247_Resource Archiver 题意: 有n个资源串,m个病毒串,现在要将所有的资源串整合到一个串内,并且这个串不能包括病毒串,问最短的串长为多少 题解: 将资源串和病 ...
- HDU - 3247 Resource Archiver (AC自动机,状压dp)
\(\quad\)Great! Your new software is almost finished! The only thing left to do is archiving all you ...
- 【CodeVS2800】 送外卖 最短路+状压DP
首先求出各点之间的最短路,floyed即可,注意是0-n. 然后考虑状压,f[i][j]表示状态为i时访问j点时的最短路和,1表示访问,0表示未访问,然后第j个点所在的位置就是(1<<j) ...
随机推荐
- AngularJS中选择样式
代码下载:https://files.cnblogs.com/files/xiandedanteng/angularJSSelectClass.rar 要点,{{ctrl.name}}比<spa ...
- vue sync
1.使用vue cli建立工程 2.在APP.vue中: <template> <div class="details"> <myComponent ...
- Struts2学习八----------接收参数
© 版权声明:本文为博主原创文章,转载请注明出处 接收参数 - 使用Action的属性接收参数 - 使用Domain Model接收参数 - 使用ModelDriven接收参数 实例 1.项目结构 2 ...
- jsp 导出excel
设置头文件 <% response.setHeader( "Pragma ", "public"); response.setHeader( " ...
- [jjzhu学java]之solr4.9同步mysql数据
Solr是一个高性能,採用Java5开发,基于Lucene的全文搜索server.同一时候对其进行了扩展,提供了比Lucene更为丰富的查询语言,同一时候实现了可配置.可扩展并对查询性能进行了优化,而 ...
- SkipList跳表(一)基本原理
一直听说跳表这个数据结构,说要学一下的,懒癌犯了,是该治治了 为什么选择跳表 目前经常使用的平衡数据结构有:B树.红黑树,AVL树,Splay Tree(这个树好像还没有听说过),Treep(也没有听 ...
- 小东和三个朋友一起在楼上抛小球,他们站在楼房的不同层,假设小东站的楼层距离地面N米,球从他手里自由落下,每次落地后反跳回上次下落高度的一半,并以此类推知道全部落到地面不跳,求4个小球一共经过了多少米?(数字都为整数) 给定四个整数A,B,C,D,请返回所求结果。
include #include<vector> using namespace std; class Balls { public: int calcDistance(int A, in ...
- HTML中Select的使用详解
<html><head><SCRIPT LANGUAGE="JavaScript"><!--//oSelect 列表的底部添加了一个新选项 ...
- Mac修改默认python版本
研究python爬虫,需要用到Beautiful Soup 但是Mac默认的python版本为2.7 自己安装了3.6的版本 import 报错 查找资料: Mac在启动,会先加载系统配置文件(包括~ ...
- Ejabberd作为推送服务的优化手段(转)
AVOS Cloud目前还在用Ejabberd做Android的消息推送服务.当时选择Ejabberd,是因为Ejabberd是一个发展很长时间的XMPP实现,并且基于Erlang,设想能在我们自主研 ...