HDU 3247-Resource Archiver(AC自动机+BFS+DP)
来源:互联网 发布:上海交通卡充值软件下载 编辑:程序博客网 时间:2024/06/05 16:50
Resource Archiver
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 100000/100000 K (Java/Others)Total Submission(s): 2837 Accepted Submission(s): 909
Problem Description
Great! Your new software is almost finished! The only thing left to do is archiving all your n resource files into a big one.
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.
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.
Input
There will be at most 10 test cases, each begins with two integers in a single line: n and m (2 <= n <= 10, 1 <= m <= 1000). The next n lines contain the resources, one in each line. The next m lines contain the virus codes, one in each line. The resources and virus codes are all non-empty 01 strings without spaces inside. Each resource is at most 1000 characters long. The total length of all virus codes is at most 50000. The input ends with n = m = 0.
Output
For each test case, print the length of shortest string.
Sample Input
2 21110011110110010 0
Sample Output
5
Source
2009 “NIT Cup” National Invitational Contest
Recommend
题意:给你n个合法字符串和m个非法字符串,让你构造一个包含所有的合法字符串(可以重叠),不包含任何一个非法字符串,并且使得这个目标字符串的长度尽可能小,问你最小长度是多少。
题解:一开始的思路是将所有的合法序列的结尾处做一个不同于非法序列的特殊标记,然后定义一个二维的dp数组保存当前的目标字符串匹配到第j个节点且已经过j个所标记的合法结点的最小长度,然后wa上天,想了许久,发现可能走过的结点是已经走过的。。。很难受,于是看了一发正解,大体思路是先用bfs求出所有合法序列末尾结点与其他所有合法状态之间的距离,又因为合法的序列结点很少,故可以用状态压缩的形式保存当前匹配状态(刷了这么多的状压,关键时候还是没想到用他。。。。)之后就知道干什么了,用dp保存一下当前的最小长度即可。
dp[i][j]:当前匹配的合法序列状态为i且以j结点(合法结点)结尾的最小长度。
#include<map> #include<stack> #include<queue> #include<vector> #include<string>#include<math.h> #include<stdio.h> #include<iostream> #include<string.h> #include<stdlib.h> #include<algorithm> using namespace std; typedef long long ll; #define inf 1000000000 #define mod 1000000007 #define maxn 62005 #define lowbit(x) (x&-x) #define eps 1e-10 int pre[maxn],a[maxn][2],flag[maxn],size,n,m,k,cnt;int d[1025][55],dis[maxn],pnt[55],path[55][55],dp[maxn][60];char s[10500];queue<int>q;void insert(int num) { int i,len=strlen(s),now=0,cnt=0; for(i=0;i<len;i++) { int v=s[i]-'0'; if(!a[now][v]) { flag[size]=0; memset(a[size],0,sizeof(a[size])); a[now][v]=size++; } now=a[now][v]; } if(num==-1)flag[now]=-1; elseflag[now]|=(1<<num);} void build_fail() { int now,i; for(i=0;i<2;i++) { int tmp=a[0][i]; if(tmp) pre[tmp]=0,q.push(tmp); } while(q.empty()==0) { now=q.front(); q.pop(); for(i=0;i<2;i++) { if(a[now][i]==0) { a[now][i]=a[pre[now]][i]; continue; } int v=pre[now];while(v && a[v][i]==0)v=pre[v]; pre[a[now][i]]=a[v][i]; q.push(a[now][i]); if(flag[pre[now]]==-1)flag[a[now][i]]=-1;elseflag[a[now][i]]|=flag[pre[now]]; } } }void bfs(int x){int i;for(i=0;i<size;i++)dis[i]=inf;q.push(pnt[x]);dis[pnt[x]]=0;while(q.empty()==0){int u=q.front();q.pop();for(i=0;i<2;i++){int v=a[u][i];if(flag[v]<0 || dis[v]!=inf)continue;dis[v]=dis[u]+1;q.push(v);}}for(i=1;i<=cnt;i++)path[x][i]=dis[pnt[i]];}void work(){int i,j,k;for(i=0;i<(1<<n);i++)for(j=1;j<=cnt;j++)dp[i][j]=inf;dp[0][1]=0;for(i=0;i<(1<<n);i++)for(j=1;j<=cnt;j++){if(dp[i][j]==inf)continue;for(k=1;k<=cnt;k++)dp[i|flag[pnt[k]]][k]=min(dp[i|flag[pnt[k]]][k],dp[i][j]+path[j][k]);}int ans=inf;for(i=1;i<=cnt;i++)ans=min(ans,dp[(1<<n)-1][i]);printf("%d\n",ans);}int main(void) { int i; while(scanf("%d%d",&n,&m)!=EOF) { if(m==0 && n==0)break; size=1;flag[0]=0;cnt=0; memset(pre,0,sizeof(pre)); memset(a[0],0,sizeof(a[0])); for(i=0;i<n;i++){scanf("%s",s);insert(i);}for(i=0;i<m;i++){scanf("%s",s);insert(-1);} build_fail();for(i=0;i<size;i++)if(i==0 || flag[i]>0)pnt[++cnt]=i;for(i=1;i<=cnt;i++)bfs(i);work();} return 0; }
阅读全文
1 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)
- hdu3341 Resource Archiver AC自动机+DP
- 【AC自动机】 HDOJ 3247 Resource Archiver
- hdu3247 Resource Archiver AC自动机+状态压缩DP
- HDU 3247 ac自动机+bfs+状态压缩dp
- HDOJ-3427 & ZOJ-3190 Resource Archiver AC自动机压缩状态DP..
- hdu 3247 Resource Archiver
- 将javaBean转换成XML
- GCC学习日志
- worldwind 地图显示字体修改
- C++删除单链表中值重复的结点
- spring学习----aop配置demo
- HDU 3247-Resource Archiver(AC自动机+BFS+DP)
- 学习Spring必学的Java基础知识(2)----动态代理
- opencv感兴趣区图像叠加
- powerdesigner向MySQL导入数据
- H5中启动Android app
- CentOS7mini配置Tomcat
- hdu 6096 String 字典树
- Object主要方法的总结
- SpringMVC 和 MyBatis 支持 Jackson 的经验谈