给定N个长度不超过20的模式串,再给定一个长度为M的目标串S,求在目标串S上最少改变多少字符,可以使得它不包含任何的模式串

建立Trie图,求得每个节点是否是不可被包含的串,然后进行DP

dp[i][j]表示在Trie图上行走i步到达节点j的要修改的最小次数,则

dp[i + 1][chi[j][k]] = min(dp[i + 1][chi[j][k]], dp[i][j] + (ACGT[k] != str[i]))

chi[j][k]表示节点j的第k个子节点

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std; const int N = 2000, CH = 4;
const int INF = 0x3F3F3F3F;
const char *ACGT = "ACGT";
int Hash[128]; struct trie{
trie *next[CH];
trie *fail;
int cnt, id;
}tree[N]; bool flag[1000];
int chi[1008][4]; class AC_Auto{ public: int nxt;
trie *root; AC_Auto(){
root = &tree[0];
nxt=0;
memset(&tree[0], 0, sizeof(trie));
} void insert(char *s){
trie *p = root;
for(int i = 0; s[i]; i++){
int c = Hash[s[i]];
if(!p -> next[c]){
memset(&tree[++nxt], 0, sizeof(trie));
p -> next[c] = &tree[nxt];
p -> next[c] -> id = nxt;
}
p = p -> next[c];
}
p -> cnt = 1;
flag[p->id] = 1;
} void build(){
queue<trie *> q;
q.push(root);
root -> fail = NULL;
while(!q.empty()){
trie *cur = q.front();
q.pop();
if(cur -> fail && flag[cur->fail ->id ]){
flag[cur -> id] = 1;
}
for(int i = 0; i < CH; i++){
trie *son = cur -> next[i];
trie *tp = (cur == root)? root: cur -> fail->next[i];
if(son == NULL){
cur -> next[i] = tp;
}else{
son -> fail = tp;
q.push(son);
}
son = cur ->next[i];
chi[cur -> id][i] = son -> id;
}
}
} }; char str[1008];
int dp[1008][1000];
int main(){
Hash['A'] = 0;
Hash['C'] = 1;
Hash['G'] = 2;
Hash['T'] = 3; int n;
int t = 0;
while(~scanf("%d", &n) && n){
AC_Auto ac;
memset(flag, 0, sizeof(flag));
memset(dp, 0x3F, sizeof(dp));
for(int i = 0; i < n; i++){
scanf("%s", str);
ac.insert(str);
} ac.build(); dp[0][0] = 0;
scanf("%s", str);
int num = ac.nxt + 1; int len = 0;
for(int i = 0; str[i]; i++, len++){
for(int j = 0; j < num; j++){
for(int k = 0; k < CH; k++){
if(flag[chi[j][k]] == 0){
dp[i + 1][chi[j][k]] = min(dp[i + 1][chi[j][k]], dp[i][j] + (ACGT[k] != str[i]));
}
}
}
}
int ans = INF;
for(int i = 0; i < num ; i++){
ans = min(ans, dp[len][i]);
}
if(ans >= INF){
ans = -1;
}
printf("Case %d: %d\n", ++t, ans);
}
return 0;
}

  

POJ3691 DNA repair(AC自动机 DP)的更多相关文章

  1. HDU2457 DNA repair —— AC自动机 + DP

    题目链接:https://vjudge.net/problem/HDU-2457 DNA repair Time Limit: 5000/2000 MS (Java/Others)    Memory ...

  2. HDU 2457/POJ 3691 DNA repair AC自动机+DP

    DNA repair Problem Description   Biologists finally invent techniques of repairing DNA that contains ...

  3. [hdu2457]DNA repair(AC自动机+dp)

    题意:给出一些不合法的模式DNA串,给出一个原串,问最少需要修改多少个字符,使得原串中不包含非法串. 解题关键:多模式串匹配->AC自动机,求最优值->dp,注意在AC自动机上dp的套路. ...

  4. POJ 3691 DNA repair(AC自动机+DP)

    题目链接 能AC还是很开心的...此题没有POJ2778那么难,那个题还需要矩阵乘法,两个题有点相似的. 做题之前,把2778代码重新看了一下,回忆一下当时做题的思路,回忆AC自动机是干嘛的... 状 ...

  5. HDU 2457 DNA repair (AC自动机+DP)

    题意:给N个串,一个大串,要求在最小的改变代价下,得到一个不含上述n个串的大串. 思路:dp,f[i][j]代表大串中第i位,AC自动机上第j位的最小代价. #include<algorithm ...

  6. hdu_2457_DNA repair(AC自动机+DP)

    题目连接:hdu_2457_DNA repair 题意: 给你N个字符串,最后再给你一个要匹配的串,问你最少修改多少次,使得这个串不出现之前给的N的字符串 题解: 刚学AC自动机,切这题还真不知道怎么 ...

  7. poj 2778 DNA Sequence AC自动机DP 矩阵优化

    DNA Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11860   Accepted: 4527 Des ...

  8. POJ 2778 DNA Sequence (AC自动机+DP+矩阵)

    题意:给定一些串,然后让你构造出一个长度为 m 的串,并且不包含以上串,问你有多少个. 析:很明显,如果 m 小的话 ,直接可以用DP来解决,但是 m 太大了,我们可以认为是在AC自动机图中,根据离散 ...

  9. HDU 2425 DNA repair (AC自动机+DP)

    DNA repair Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

随机推荐

  1. CH Round #55 - Streaming #6 (NOIP模拟赛day2)解题报告

    T1九九归一 描述 萌蛋在练习模n意义下的乘法时发现,总有一些数,在自乘若干次以后,会变成1.例如n=7,那么5×5 mod 7=4,4×5 mod 7=6,6×5 mod 7=2,2×5 mod 7 ...

  2. Java WebClient 总结

    private WebClient getAWebClient() { WebClient webClient = new WebClient(BrowserVersion.FIREFOX_24); ...

  3. STS新建的maven项目报错问题

    STS新建的maven项目报错问题 解决方法:打开pom.xml文件添加 <dependency> <groupId>javax.servlet</groupId> ...

  4. Jenkins 报错:(pending—Waiting for next available executor)

    系统管理-管理节点,刷新状态

  5. java的事务处理

    本文转自http://zhenchengchagangzi.iteye.com/blog/1159493 java的事务处理,如果对数据库进行多次操作,每一次的执行或步骤都是一个事务.如果数据库操作在 ...

  6. Nginx反向代理到Tomcat服务器

    在实际生产中,Tomcat服务器一般不单独使用在项目中,对于静态资源的响应Nginx表现的比较好,另外由于nginx是专门用于反向代理的服务器,所以很容易实现将java的请求转发到后端交给tomcat ...

  7. 20. javacript高级程序设计-JSON

    1. JSON JSON是一种数据格式,存在以下三种类型的值: l 简单值:使用与JavaScript相同的语法,可以在JSON中表示字符串.数值.布尔值和null,不支持 undefined,例如: ...

  8. ASM:《X86汇编语言-从实模式到保护模式》第14章:保护模式下的特权保护和任务概述

    ★PART1:32位保护模式下任务的隔离和特权级保护  这一章是全书的重点之一,这一张必须要理解特权级(包括CPL,RPL和DPL的含义)是什么,调用门的使用,还有LDT和TSS的工作原理(15章着重 ...

  9. jquery.dataTable分页

    jsp页面,引入几个js <link type="text/css" rel="stylesheet" href="/library/css/b ...

  10. 【python】list,dict赋值不要用等号,要用extend,update

    如果有一个list,我们用连等号的方式赋值 c = d = [1], 则当c改变时,d同样会改变.字典同理 正确做法应该是: d = [1] c = [1] 或者 d = [1] c.extend(d ...