题目,求最短的包含所有n个DNA片段且不包含任何一个病毒片段的序列。

容易用所有DNA片段和病毒片段建一个AC自动机,构造fail时处理一下各个结点后缀是DNA或者病毒的情况,然后dp[S][u]表示包含DNA片段的集合是S的且后缀状态是自动机第u个结点的最短序列长度,然后顺着AC自动机避开病毒串转移。

不过构建的AC自动机结点上限60000左右,集合有1024个状态,这样内存开不下。看了题解,原来不必要考虑自动机所有结点——

  • dp[S][u]表示包含DNA片段集合是S且后缀是第u个DNA片段的最短序列长度
  • 通过BFS预处理出各个DNA片段到其他DNA片段在AC自动机上的距离,要注意某些DNA片段的后缀包含其他DNA片段的情况,还有跳过后缀包含病毒串的结点。
  • 转移就是dp[S][u]=max(dp[S-{u}][v]+dist[v][u])(v∈S-{u})

这个解法的正确性我还得消化消化。。

 #include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#define INF (1<<29)
#define MAXN 66666
int tn,ch[MAXN][],fail[MAXN],flag[MAXN];
int idx[];
void insert(char *s,int k){
int x=;
for(int i=; s[i]; ++i){
int y=s[i]-'';
if(ch[x][y]==) ch[x][y]=++tn;
x=ch[x][y];
}
if(k==- || flag[x]==-) flag[x]=-;
else{
idx[k]=x;
flag[x]|=(<<k);
}
}
int que[MAXN],front,rear;
void getfail(){
memset(fail,,sizeof(fail));
front=rear=;
if(ch[][]) que[rear++]=ch[][];
if(ch[][]) que[rear++]=ch[][];
while(front<rear){
int x=que[front++];
for(int i=; i<; ++i){
if(ch[x][i]){
que[rear++]=ch[x][i];
fail[ch[x][i]]=ch[fail[x]][i];
if(flag[ch[x][i]]==- || flag[ch[fail[x]][i]]==-) flag[ch[x][i]]=-;
else flag[ch[x][i]]|=flag[ch[fail[x]][i]];
}else ch[x][i]=ch[fail[x]][i];
}
}
} int n,m,dist[MAXN],G[][];
void BFS(int k){
memset(dist,,sizeof(dist));
dist[idx[k]]=;
front=rear=;
que[rear++]=idx[k];
while(front<rear){
int x=que[front++];
if(flag[x]){
for(int i=; i<n; ++i){
if(((flag[x]>>i)&)==) continue;
G[k][i]=min(G[k][i],dist[x]-);
}
}
for(int i=; i<; ++i){
int y=ch[x][i];
if(flag[y]==- || dist[y]) continue;
dist[y]=dist[x]+;
que[rear++]=y;
}
}
}
int d[<<][],len[];
int main(){
char str[];
while(~scanf("%d%d",&n,&m) && (n||m)){
tn=;
memset(ch,,sizeof(ch));
memset(flag,,sizeof(flag));
for(int i=; i<n; ++i){
scanf("%s",str);
insert(str,i);
len[i]=strlen(str);
}
for(int i=; i<m; ++i){
scanf("%s",str);
insert(str,-);
}
getfail();
for(int i=; i<n; ++i){
for(int j=; j<n; ++j) G[i][j]=INF;
}
for(int i=; i<n; ++i){
BFS(i);
}
for(int i=; i<(<<n); ++i){
for(int j=; j<n; ++j) d[i][j]=INF;
}
for(int i=; i<n; ++i){
d[<<i][i]=len[i];
}
for(int i=; i<(<<n); ++i){
for(int j=; j<n; ++j){
if(((i>>j)&)==) continue;
for(int k=; k<n; ++k){
if(((i>>k)&)== || j==k) continue;
d[i][j]=min(d[i][j],d[i^(<<j)][k]+G[k][j]);
}
}
}
int res=INF;
for(int i=; i<n; ++i) res=min(res,d[(<<n)-][i]);
printf("%d\n",res);
}
return ;
}

HDU3247 Resource Archiver(AC自动机+BFS+DP)的更多相关文章

  1. HDU3247 Resource Archiver —— AC自动机 + BFS最短路 + 状压DP

    题目链接:https://vjudge.net/problem/HDU-3247 Resource Archiver Time Limit: 20000/10000 MS (Java/Others)  ...

  2. 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 ...

  3. HDU 3247 Resource Archiver (AC自动机+BFS+状压DP)

    题意:给定 n 个文本串,m个病毒串,文本串重叠部分可以合并,但合并后不能含有病毒串,问所有文本串合并后最短多长. 析:先把所有的文本串和病毒都插入到AC自动机上,不过标记不一样,可以给病毒标记-1, ...

  4. HDU - 3247 Resource Archiver (AC自动机,状压dp)

    \(\quad\)Great! Your new software is almost finished! The only thing left to do is archiving all you ...

  5. hdu_3247_Resource Archiver(AC自动机+bfs+TSP)

    题目链接:hdu_3247_Resource Archiver 题意: 有n个资源串,m个病毒串,现在要将所有的资源串整合到一个串内,并且这个串不能包括病毒串,问最短的串长为多少 题解: 将资源串和病 ...

  6. 【HDU3530】 [Sdoi2014]数数 (AC自动机+数位DP)

    3530: [Sdoi2014]数数 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 682  Solved: 364 Description 我们称一 ...

  7. 关于AC自动机和DP的联系

    首先是描述个大概.不说一些特殊的DP 或者借用矩阵来状态转移 (这些本质都是一样的). 只讲AC自动机和DP的关系(个人理解). AC自动机 又可以叫做状态机. 我一开始的认为.AC 自动机提供了一些 ...

  8. 【bzoj3530】[Sdoi2014]数数 AC自动机+数位dp

    题目描述 我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串.例如当S=(22,333,0233)时,233是幸运数,2333.20233.3223不是幸运 ...

  9. BZOJ 3530 [SDOI2014]数数 (Trie图/AC自动机+数位DP)

    题目大意:略 裸的AC自动机+数位DP吧... 定义f[i][x][0/1]表示已经匹配到了第i位,当前位置是x,0表示没到上限,1到上限,此时数是数量 然而会出现虚拟前导零,即前几位没有数字的情况, ...

随机推荐

  1. App架构设计经验谈:服务端接口的设计

    App与服务器的通信接口如何设计得好,需要考虑的地方挺多的,在此根据我的一些经验做一些总结分享,旨在抛砖引玉. 安全机制的设计 现在,大部分App的接口都采用RESTful架构,RESTFul最重要的 ...

  2. SGU 170 Particles(规律题)

    题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=170 解题报告:输入两个由'+'和'-'组成的字符串,让你判断第二个串能不能由第一个 ...

  3. [BZOJ1067][SCOI2007]降雨量

    [BZOJ1067][SCOI2007]降雨量 试题描述 我们常常会说这样的话:“X年是自Y年以来降雨量最多的”.它的含义是X年的降雨量不超过Y年,且对于任意 Y<Z<X,Z年的降雨量严格 ...

  4. 转:PCL+VS2010环境配置

    1.下载 http://www.pointclouds.org/downloads/windows.html出下载PCL完全安装包1.6.0 all-in-one-installer,我的电脑是32位 ...

  5. Floyd算法 及其运用

    #include<stdio.h> ][]; ][]; void floyd(int n) { ;k<=n;k++) { ;i<=n;i++) { ;j<=n;j++) ...

  6. JSoup——用Java解析html网页内容

    当需要从网页上获取信息时,需要解析html页面.筛选指定标签,并获取其值是必不可少的操作,解析html页面这方面的利器,Python有BeautifulSoup,Java一直没有好的工具,之前的Htm ...

  7. catalog、scheme区别

    按照SQL标准的解释,在SQL环境下Catalog和Schema都属于抽象概念,可以把它们理解为一个容器或者数据库对象命名空间中的一个层次,主要用来解决命名冲突问题.从概念上说,一个数据库系统包含多个 ...

  8. 《转》VS2012发布网站详细步骤

    本文转载自MannyGuo 如果给您带来不便请联系博主 1.打开你的VS2012网站项目,右键点击项目>菜单中 重新生成一下网站项目:再次点击右键>发布: 2.弹出网站发布设置面板,点击& ...

  9. python动态获取对象的属性和方法

    http://blog.csdn.net/kenkywu/article/details/6822220首先通过一个例子来看一下本文中可能用到的对象和相关概念.01     #coding: UTF- ...

  10. 转centos65安装简测mysql cluster 7.3.7

    MySQLCluster是sharednothing分布式架构,ndb存储引擎把数据放置于内存中.可以做到无单点故障.由运行于不同服务器上的的多种进程构成,组件包括SQL节点,NDBD数据节点,管理程 ...