给定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. innerHtml innerText textContent兼容性问题

    innerHtml,innerText,textContentinnerHtml获取元素带标签的内容:innerText只获取元素的文本:火狐不支持innerText,支持textContent: / ...

  2. java复制文件

    package com.test.tes; import java.io.File; import java.io.FileInputStream; import java.io.FileOutput ...

  3. centos 6.5 git 服务器的配置(入门级)

    参考:https://www.digitalocean.com/community/tutorials/how-to-set-up-a-private-git-server-on-a-vps http ...

  4. TCP的几个状态

    转自: TCP的几个状态 (SYN, FIN, ACK, PSH, RST, URG)     http://www.cnblogs.com/lidabo/p/5713569.html

  5. C#之常见数组编码错误

    摘抄自C#本质论(第四版,P55) 常见错误 错误描述 改正后的代码 int numbers[] 用于声明数组的方括号放在数据类型之后,而不是在变量标识符之后 int[] numbers; int[] ...

  6. Appium+Robotframework实现Android应用的自动化测试-5:RIDE中AppiumLibrary的配置

    可能很多朋友已经迫不及待的想要用RobotFramework+AppiumLibrary来写Android App的测试脚本了,那我们也废话少说,直接开始. 首先打开RIDE,这是编写RobotFra ...

  7. zookeeper部署及集群测试

    zookeeper部署及集群测试 环境 三台测试机 操作系统: centos7 ; hostname: c1 ; ip: 192.168.1.80 操作系统: centos7 ; hostname: ...

  8. 使用Java中的IO流,把A文件里的内容输入到B文件中

    我们先创建两个文本文件,out.txt和in.txt,在out.txt中输入"Hello World",然后使用FileInputStream把字符串读取出来,再使用FileOut ...

  9. iOS 关于UIWindow的理解

    Every iOS app has a window that handles the presentation of the app’s user interface. Although the w ...

  10. CentOs7 网卡出现问题Job for network.service failed

    centos7网卡是需要写入MAC地址的不然启动不了 在运行“/etc/init.d/network restart”命令时,出现错误“Job for network.service failed.  ...