Hdu 2457 DNA repair (ac自己主动机+dp)
题目大意:
改动文本串的上的字符,使之不出现上面出现的串。问最少改动多少个。
思路分析:
dp[i][j]表示如今 i 个字符改变成了字典树上的 j 节点。
然后顺着自己主动机一直转移方程。
注意合法与不合法。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define inf 0x3f3f3f3f
using namespace std; const char tab = 0;
const int max_next = 4;
int idx;
struct trie
{
struct trie *fail;
struct trie *next[max_next];
int isword;
int index;
trie()
{
isword=0;
memset(next,NULL,sizeof next);
fail=NULL;
}
};
int rev[256];
trie *que[100005],ac[100005];
int head,tail; trie *New()
{
trie *temp=&ac[idx];
for(int i=0;i<4;i++)temp->next[i]=NULL;
temp->fail=NULL;
temp->isword=0;
temp->index=idx++;
return temp;
}
void Insert(trie *root,char *word,int len){
trie *t=root;
for(int i=0;i<len;i++){
if(t->next[rev[word[i]]]==NULL)
t->next[rev[word[i]]]=New();
t=t->next[rev[word[i]]];
}
t->isword++;
} void acbuild(trie *root){
int head=0,tail=0;
que[tail++]=root;
root->fail=NULL;
while(head<tail){
trie *temp=que[head++],*p;
for(int i=0;i<max_next;i++){
if(temp->next[i]){
if(temp==root)temp->next[i]->fail=root;
else {
p=temp->fail;
while(p!=NULL){
if(p->next[i]){
temp->next[i]->fail=p->next[i];
break;
}
p=p->fail;
}
if(p==NULL)temp->next[i]->fail=root;
}
if(temp->next[i]->fail->isword)temp->next[i]->isword++;
que[tail++]=temp->next[i];
}
else if(temp==root)temp->next[i]=root;
else temp->next[i]=temp->fail->next[i];
}
}
} void del(trie *root)
{
for(int i=0;i<max_next;i++)
if(root->next[i])del(root->next[i]);
free(root);
} int dp[2005][2005];
int solve(char *word,int len)
{
memset(dp,0x3f,sizeof dp);
dp[0][0]=0;
for(int i=1;i<=len;i++)
{
for(int j=0;j<idx;j++)
{
if(ac[j].isword)continue;
if(dp[i-1][j]==inf)continue;
for(int k=0;k<4;k++)
{
int p=ac[j].next[k]->index;
if(ac[p].isword)continue;
dp[i][p]=min(dp[i][p],dp[i-1][j]+(k!=rev[word[i-1]]));
}
}
}
int ans=inf;
for(int i=0;i<idx;i++)
ans=min(ans,dp[len][i]);
return ans==inf? -1:ans;
}
char word[10005];
int main()
{
rev['A']=0;
rev['G']=1;
rev['C']=2;
rev['T']=3; int n,cas=1;
while(scanf("%d",&n)!=EOF && n)
{
idx=0;
trie *root=New();
for(int i=1;i<=n;i++)
{
scanf("%s",word);
Insert(root,word,strlen(word));
}
acbuild(root);
scanf("%s",word);
printf("Case %d: %d\n",cas++,solve(word,strlen(word)));
}
return 0;
}
Hdu 2457 DNA repair (ac自己主动机+dp)的更多相关文章
- POJ 3691 & HDU 2457 DNA repair (AC自己主动机,DP)
http://poj.org/problem?id=3691 http://acm.hdu.edu.cn/showproblem.php?pid=2457 DNA repair Time Limit: ...
- POJ 2778 DNA Sequence (AC自己主动机 + dp)
DNA Sequence 题意:DNA的序列由ACTG四个字母组成,如今给定m个不可行的序列.问随机构成的长度为n的序列中.有多少种序列是可行的(仅仅要包括一个不可行序列便不可行).个数非常大.对10 ...
- HDU - 2825 Wireless Password(AC自己主动机+DP)
Description Liyuan lives in a old apartment. One day, he suddenly found that there was a wireless ne ...
- HDU 2457 DNA repair (AC自动机+DP)
题意:给N个串,一个大串,要求在最小的改变代价下,得到一个不含上述n个串的大串. 思路:dp,f[i][j]代表大串中第i位,AC自动机上第j位的最小代价. #include<algorithm ...
- HDU 2457 DNA repair(AC自动机+DP)题解
题意:给你几个模式串,问你主串最少改几个字符能够使主串不包含模式串 思路:从昨天中午开始研究,研究到现在终于看懂了.既然是多模匹配,我们是要用到AC自动机的.我们把主串放到AC自动机上跑,并保证不出现 ...
- poj 3691 DNA repair(AC自己主动机+dp)
DNA repair Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 5877 Accepted: 2760 Descri ...
- Hdu 3341 Lost's revenge (ac+自己主动机dp+hash)
标题效果: 举个很多种DNA弦,每个字符串值值至1.最后,一个长字符串.要安排你最后一次另一个字符串,使其没事子值和最大. IDEAS: 首先easy我们的想法是想搜索的!管她3721..直接一个字符 ...
- HDU 2825 Wireless Password (AC自己主动机,DP)
pid=2825">http://acm.hdu.edu.cn/showproblem.php? pid=2825 Wireless Password Time Limit: 2000 ...
- HDU 2896 病毒侵袭 (AC自己主动机)
pid=2896">http://acm.hdu.edu.cn/showproblem.php?pid=2896 病毒侵袭 Time Limit: 2000/1000 MS (Java ...
随机推荐
- Setup Factory 读取安装包的配置文件
result = INIFile.GetValue(SessionVar.Expand("%SourceFolder%\\set.ini"), "set", & ...
- UCOS2_STM32移植详细过程(汇总)
Ⅰ.概述 笔者发现一个问题,很多初学者,甚至很多工作一两年的人,他们有一种依赖的思想,就是希望从别处获取的软件代码不做任何修改,直接可以运行或者使用.笔者想说,实践才是检验真理的关键,实践才是掌握知识 ...
- Android基础总结(六)Activity
创建第二个Activity(掌握) 需要在清单文件中为其配置一个activity标签 标签中如果带有这个子节点,则会在系统中多创建一个快捷图标 <intent-filter> <ac ...
- 关于ubuntu系统boot分区空间不足而又无法卸载旧内核的解决方法
2016年09月03日 14:16:45 萧氏一郎 阅读数:7802 标签: ubuntuboot分区清理更多 个人分类: linux 版权声明:本文为本猿原创文章,转载务必注明出处,多谢. ht ...
- 常用的easyui使用方法之二
-------datagrid 1.获取某行的行号(row)tdg.datagrid('getRowIndex',rows)2.通过行号移除该行tdg.datagrid('deleteRow',ind ...
- TensorFlow基础笔记(6) 图像风格化实验
参考 http://blog.csdn.net/wspba/article/details/53994649 https://www.ctolib.com/AdaIN-style.html Ackno ...
- centos7安装avahi
sudo yum install avahi sudo yum install avahi-tools 转自: http://unix.stackexchange.com/questions/1829 ...
- PHP中strlen和mb_strlen函数的区别
strlen strlen — 获取字符串长度 int strlen ( string $string ) 返回给定的字符串 string 的长度. mb_strlen int mb_strlen ( ...
- System.in中的read()方法
大家先来看例如以下这个程序 public class TestInputStream { public static void main(String args[]) throws IOExcepti ...
- C++ enum 枚举类型
1. 枚举类型浅谈 假设我们要设计一个打开文件的函数, 打开文件由三种状态: input, output 和 append. 不使用枚举, 我们可能会写出如下的代码 const int input = ...