http://blog.csdn.net/kk303/article/details/6929641

http://blog.csdn.net/human_ck/article/details/6577142

建立AC自动机以后,把所有单词结点标记出来,不要忘记,如果某个结点虽然原本不是单词结点,但其fail指针指向了一个单词结点,那么其也需要被标记为单词结点。

然后对于每个空的儿子本来应该在Trie上跳跃,但是我们可以直接让空的儿子指向其父的fail的那个对应的儿子,就没必要跳了,这样可以不用重复计算。

具体怎么转移网上到处都有。

要说明的一点是,这个dp是你对于原串的每一个前缀,都考虑了其所对应的一切可能的“安全序列”,并且这个状态没有后效性,从而保证了dp的正确性。

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define INF 2147483647
queue<int>q;
int child[1010][4],fail[1010],size,ma[1010],f[1010][1010],ans;
bool word[1010];
void Insert(char S[])
{
int len=strlen(S);
int now=0;
for(int i=0;i<len;++i)
{
if(!child[now][ma[S[i]]])
child[now][ma[S[i]]]=size++;
now=child[now][ma[S[i]]];
}
word[now]=1;
}
void build()
{
fail[0]=-1;
q.push(0);
while(!q.empty())
{
int U=q.front(); q.pop();
for(int i=0;i<4;++i)
if(child[U][i])
{
int V=fail[U];
while(V!=-1)
{
if(child[V][i])
{
fail[child[U][i]]=child[V][i];
break;
}
V=fail[V];
}
if(V==-1)
fail[child[U][i]]=0;
if(word[fail[child[U][i]]])
word[child[U][i]]=1;//如果某个单词是该结点所在单词的前缀,那么该结点也应被标记为单词结点
q.push(child[U][i]);
}
else if(U)
child[U][i]=child[fail[U]][i];//当然你在dp过程中在Trie上跳也行,但这样就避免了重复计算
//由于BFS,其实形成了一个类似链表的结构
}
}
void Init()
{
memset(child,0,sizeof(child));
memset(fail,0,sizeof(fail));
memset(word,0,sizeof(word));
size=1;
}
int T,n,m;
char s[1010];
int main()
{
//freopen("poj3691.in","r",stdin);
ma['A']=0; ma['G']=1; ma['C']=2; ma['T']=3;
while(1)
{
scanf("%d",&n);
if(!n)
break;
Init();
for(int i=1;i<=n;++i)
{
scanf("%s",s);
Insert(s);
}
build();
memset(f,0x7f,sizeof(f));
f[0][0]=0;
scanf("%s",s);
m=strlen(s);
for(int i=0;i<m;++i)
for(int j=0;j<size;++j)
for(int k=0;k<4;++k)
if(!word[child[j][k]])
f[i+1][child[j][k]]=min(f[i+1][child[j][k]],f[i][j]+(ma[s[i]]!=k));
ans=INF;
for(int i=0;i<size;++i)
ans=min(ans,f[m][i]);
printf("Case %d: %d\n",++T,ans<=1000 ? ans : (-1));
}
return 0;
}

最新文章

  1. 多个精美的导航样式web2.0源码
  2. Servlet监听器
  3. hibernate考试题
  4. Django1.8教程——从零开始搭建一个完整django博客(三)
  5. OC基础(8)
  6. python中列表,元组,字符串如何互相转换
  7. 理解JavaScript原型式继承
  8. HDU 4430 Yukari&#39;s Birthday (二分+枚举)
  9. 用户体验设置和UI设计的10个不同点
  10. python高级编程之元类(第3部分结束)
  11. openStack images概念及维护
  12. windows下安装mongodb以及node.js连接mongodb
  13. 201521123052《Java程序设计》第9周学习总结
  14. Android捕获全局异常
  15. MySQL 在线更改 Schema 工具
  16. 开发神器之PHPstorm配置及使用
  17. 【转载】Pytorch tutorial 之Datar Loading and Processing
  18. presto 函数中使用子查询
  19. quartz获取缓存中所有运行中的Job
  20. [luogu3369][普通平衡树]

热门文章

  1. 原生ajax方法封装
  2. webpack 3.8 使用 extract-text-webpack-plugin 3.0 抽取css失败:You may need an appropriate loader to handle this file type.
  3. HDU 5670
  4. HDU1054 Strategic Game(最小点覆盖)
  5. java使用JNA调用dll
  6. 标签 JLable 类
  7. WebSocket最简易理解,term.js插件的使用
  8. 会话Cookie
  9. 虚拟机VMware 安装CentOS6.5
  10. bootstrap,ECMA