HDU 3247 Resource Archiver(AC自动机+BFS+状态DP)
来源:互联网 发布:淘宝店太坑了 编辑:程序博客网 时间:2024/06/04 17:42
题目:给出n个资源,m个病毒,将资源串拼接成一个串,必须包含所有的资源串,可以重叠,但是不能包含病毒
问最小的长度为多少
将所有的资源串和病毒串都放在Trie树里建立起来,当然作上相应的标记。然后建立fail指针之后
从资源串的结尾出发,BFS,记录能到达其它资源串结尾的步数。得到所有资源串结尾状态的距离邻接阵。
之后是状态压缩DP
dp[i][j]表示资源串的状态为i时,最后一个已取资源串是j时,最短长度。
#include <set>#include <map>#include <stack>#include <queue>#include <deque>#include <cmath>#include <vector>#include <string>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define L(i) i<<1#define R(i) i<<1|1#define INF 0x3f3f3f3f#define pi acos(-1.0)#define eps 1e-9#define maxn 60010#define MOD 1000000007int n,m;int dp[1050][13];int path[13][13];int pos[13];struct Trie{ int next[maxn][2],fail[maxn],en[maxn]; int root,L,cnt; void init() { L = 0; pos[0] = 0; root = newnode(); } int newnode() { for(int i = 0; i <= 1; i++) next[L][i] = -1; en[L++] = 0; return L-1; } void Insert(char a[],int flag) { int now = root; int len = strlen(a); for(int i = 0; i < len; i++) { int x; if(a[i] == '0') x = 0; else x = 1; if(next[now][x] == -1) next[now][x] = newnode(); now = next[now][x]; } en[now] = flag; } void build() { queue<int> Q; fail[root] = root; for(int i = 0; i <= 1; 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(en[fail[now]] == -1) en[now] = en[fail[now]]; else en[now] |= en[fail[now]]; for(int i = 0; i <= 1; 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]); } } } } void bfs(int u,int cnt) { queue<int> q; q.push(pos[u]); int dis[maxn]; memset(dis,-1,sizeof(dis)); dis[pos[u]] = 0; while(!q.empty()) { int v = q.front(); q.pop(); for(int i = 0; i < 2; i++) { int k = next[v][i]; if(dis[k] < 0 && en[k] != -1) { dis[k] = dis[v] + 1; q.push(k); } } } for(int i = 0; i < cnt; i++) path[u][i] = dis[pos[i]]; } void solve() { int cnt = 1; for(int i = 0; i < L; i++) if(en[i] > 0) pos[cnt++] = i; for(int i = 0; i < cnt; i++) bfs(i,cnt);// for(int i = 0; i <= n; i++)// {for(int j = 0; j <= n; j++)// printf("%d ",path[i][j]);printf("\n");} memset(dp,INF,sizeof(dp)); 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(path[j][k] < 0 || j == k) continue; dp[i|en[pos[k]]][k] = min(dp[i|en[pos[k]]][k],dp[i][j]+path[j][k]); } } int ans = INF; for(int i = 0; i < cnt; i++) ans = min(ans,dp[(1<<n)-1][i]); printf("%d\n",ans); }} ac;int main(){ int t,C = 1; //scanf("%d",&t); while(scanf("%d%d",&n,&m) && (n+m)) { ac.init(); char s[1010]; for(int i = 0; i < n; i++) { scanf("%s",s); ac.Insert(s,1<<i); } for(int i = 0; i < m; i++) { scanf("%s",s); ac.Insert(s,-1); } ac.build(); ac.solve(); } return 0;}
0 0
- HDU 3247 Resource Archiver(AC自动机+BFS+状态DP)
- HDU 3247 Resource Archiver(AC自动机+BFS+状态DP)
- hdu 3247 Resource Archiver(AC自动机+BFS+DP)
- hdu 3247 Resource Archiver (ac自动机+BFS+状压dp)
- HDU 3247-Resource Archiver(AC自动机+BFS+DP)
- HDU 3247 Resource Archiver (AC自动机 + BFS + 状态压缩DP)
- HDU 3247 Resource Archiver AC自动机 + BFS最短路 + 状压DP
- hdu 3247 Resource Archiver(AC自动机+状压DP)
- [AC自动机+spfa+状压dp] hdu 3247 Resource Archiver
- HDU 3247 Resource Archiver[AC自动机+最短路+dp]
- 【ZOJ】 3190 Resource Archiver AC自动机+BFS预处理+DP
- hdu3247 Resource Archiver AC自动机+状态压缩DP
- HDU3247 Resource Archiver(AC自动机+DP)
- hdu3341 Resource Archiver AC自动机+DP
- HDU 3247 ac自动机+bfs+状态压缩dp
- 【AC自动机】 HDOJ 3247 Resource Archiver
- HDOJ-3427 & ZOJ-3190 Resource Archiver AC自动机压缩状态DP..
- HDU 3247 AC自动机 + 状态压缩dp
- Linux修改Tmpfs
- 数据结构实验之二叉树三:统计叶子数
- cdh5.3.6下hue3.7.0的安装部署
- source insight context window不能显示上下文的问题
- HDU 1069 Monkey and Banana
- HDU 3247 Resource Archiver(AC自动机+BFS+状态DP)
- 【机器学习】贝叶斯分类器:朴素贝叶斯
- nginx-lua开发例子
- BZOJ2157 旅游
- SWUST 2268 SB_cyh and his BST two (Treap名次树)
- N2O游戏大师 V2.36.75.803 官方安装版
- Java Collections
- iOS开发-Realm数据库
- Hibernate基本套路(附赠HibernateUtil)