HDU 3247 Resource Archiver AC自动机 + bfs + 状态压缩dp
2014-09-16 19:27
344 查看
题意:给定你n个文本串 ,m个模式串,怎么构造最短的新的文本串使得这个新的文本串包含n个文本串的所有信息且文本串的长度最短且不包含模式串。
解题思路:这里看题解撸的,首先我们算出两两文本串的距离(end数组标记文本和模式串的值不同,利用这个进行bfs算出两两之间的最短距离,注意到这里模式串的end是不能走到的。这里也不需要松弛操作),然后因为n只有10这么大,所以我们可以状态压缩 ,dp[i][j] 表示 压缩后状态为 i(二进制压缩,每i位表示第i个是否在)且 以j结尾的文本串的最小花费。这样去dp即可。
解题代码:
View Code
解题思路:这里看题解撸的,首先我们算出两两文本串的距离(end数组标记文本和模式串的值不同,利用这个进行bfs算出两两之间的最短距离,注意到这里模式串的end是不能走到的。这里也不需要松弛操作),然后因为n只有10这么大,所以我们可以状态压缩 ,dp[i][j] 表示 压缩后状态为 i(二进制压缩,每i位表示第i个是否在)且 以j结尾的文本串的最小花费。这样去dp即可。
解题代码:
// File Name: temp.cpp // Author: darkdream // Created Time: 2014年09月11日 星期四 15时18分4秒 #include<vector> #include<list> #include<map> #include<set> #include<deque> #include<stack> #include<bitset> #include<algorithm> #include<functional> #include<numeric> #include<utility> #include<sstream> #include<iostream> #include<iomanip> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<ctime> #include<queue> #define LL long long #define maxn 60002 #define INF 0x3f3f3f3f using namespace std; int n,m; struct Trie { int next[maxn][2],fail[maxn],end[maxn]; int root, L; int newnode() { memset(next[L],-1,sizeof(next[L])); end[L++] = 0 ; return L-1; } void init() { L = 0 ; root = newnode(); } void insert(char buf[],int status) { int now = root; int len = strlen(buf); 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] = status; } void build() { queue<int> Q; fail[root] = root; for(int i = 0;i < 2;i ++) { if(next[root][i] == -1) { next[root][i] = root; //指向root 是没有问题的,我们主要是通过end 数组对个数进行计数的。 }else{ fail[next[root][i]] = root; Q.push(next[root][i]); } } while(!Q.empty()) { int now = Q.front(); Q.pop(); 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 )// bfs 因为是直接 bfs 所以没有松弛操作 { 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 query() { 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 j = 0;j < cnt;j++) ans = min(ans,dp[(1<<n)-1][j]); return ans; } }; Trie ac; char str[50005]; int main(){ while(scanf("%d %d",&n,&m ) != EOF) { if(n == 0 && m == 0 ) break; ac.init(); for(int i = 0;i < n;i ++) { scanf("%s",str); ac.insert(str,1<<i); } for(int i = 1;i <= m;i ++) { scanf("%s",str); ac.insert(str,-1); } ac.build(); printf("%d\n",ac.query()); } return 0; }
View Code
相关文章推荐
- HDU 3247 Resource Archiver (AC自己主动机 + BFS + 状态压缩DP)
- HDU 3247 Resource Archiver (AC自动机 + BFS + 状态压缩DP)
- HDU 3247 Resource Archiver(自动机+状态压缩DP)
- HDU 3247 Resource Archiver(AC自动机+状态压缩dp+最短路BFS)
- hdu 3247(ac自动机+状态压缩dp+最短路)
- HDU 3247 Resource Archiver(AC自动机+状态压缩DP)
- HDU 3247 AC自动机 + 状态压缩dp
- Hdu 4057 Rescue the Rabbit (AC自动机+状态压缩dp) - 2011 ACM-ICPC Dalian Regional Contest Problem G
- HDU 3247 Resource Archiver(AC自动机+BFS+状态DP)
- hdu 4317 Unfair Nim(状态压缩DP)——2012 Multi-University Training Contest 2
- hdu 4317 Unfair Nim (状态压缩DP) 【2012 Multi-University Training Contest 2】
- HDU_4317 Unfair Nim 状态压缩dp
- HDU 3811 DP状态压缩
- hdu 4385 Moving Bricks (状态压缩dp 2012 Multi-University Training Contest 9 )
- HDU 1074 状态压缩DP
- hdu 1565 状态压缩 dp
- HDU 3001 Travelling 【状态压缩DP】
- HDU 2825 Wireless Password(AC自动机+状态压缩DP)
- hdu 1074 DFS+状态压缩DP
- HDU 4049 状态压缩DP