题目,求最短的包含所有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. LUA之string的使用

    --string.len(s)          --返回字符串s的长度 --string.rep(s, n)--返回重复n次字符串s的串,你使用string.rep("a", 2 ...

  2. 你真的会用AsyncTask吗?(一)

    一个典型AsyncTask的. view source print? 01 public class DialogTestActivity extends Activity { 02     priv ...

  3. Bridge 使用

  4. xcode Git

    http://blog.csdn.net/w13770269691/article/details/38704941 在已有的git库中搭建新库,并且将本地的git仓库,上传到远程服务器的git库中, ...

  5. 【GoLang】GoLang 微服务、开源库等参考资料

    参考资料: GoLang书籍: https://github.com/dariubs/GoBooksGo名库: https://github.com/Unknwon/go-rock-libraries ...

  6. 《ASP.NET1200例》ListView控件之修改,删除与添加

    aspx <body> <form id="form1" runat="server"> <div> <asp:Lis ...

  7. 32.C++不能被继承的类[C++ Final Class]

    [题目] 用C++设计一个不能被继承的类. [分析] 这是Adobe公司2007年校园招聘的最新笔试题.这道题除了考察应聘者的C++基本功底外,还能考察反应能力,是一道很好的题目. 在Java中定义了 ...

  8. Sybase IQ如何将大文件数据迅速加载到数据库

    试想一下,如果一个文件5G.10G甚至更大.如何将它迅速地加载到数据库指定的表呢?我们看看Sybase IQ是如何迅速地将表的数据加载到数据库的. 数据文件格式: 1440,2011-01-09 00 ...

  9. 2.python基础深入(元组、字符串、列表、字典)

    一,对象与类 对象: python中一切皆为对象,所谓对象:我自己就是一个对象,我玩的电脑就是对象,玩的手机就是对象. 我们通过描述属性(特征)和行为来描述一个对象的. 在python中,一个对象的特 ...

  10. Hudson可扩展持续集成引擎

    参考文章:http://blog.csdn.net/dazhi_100/article/details/11629133 极限编程中一项建议实践便是持续集成,持续集成是指在开发阶段,对项目进行持续性自 ...