给定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. QT 信号与槽connect

    QT 信号与槽connect QT 信号与槽connect connect函数调用几个限制 connect函数代码 QT中信号与槽的连接使用的connect函数是一个静态函数,在类QObject中定义 ...

  2. Mysql5.7版本编译安装及配置

    配置yum安装方式 1.配置本地yum源 vim /etc/yum.repos.d/rhel-source.repo [rhel-source] name=Red Hat Enterprise Lin ...

  3. Minimum Adjustment Cost

    Given an integer array, adjust each integers so that the difference of every adjacent integers are n ...

  4. POJ 2503

    http://poj.org/problem?id=2503 题意就是字典翻译.这个输入输出真心恶心,要不是看discuss我肯定是解决不了,还用上了sscanf函数.... 这道题我用几种方法做. ...

  5. ios8 新增的 showViewController 和 showDetailViewController

    1.showViewController 先看看说明: You use this method to decouple the need to display a view controller fr ...

  6. 9.SpringMVC和json结合传递参数

    input的值一定要用.attribute来取值.val( )只能用可以看看开源社区jQuery的ajax请求.html():读取和修改一个元素的HTML内容,详情.html():.text():读取 ...

  7. linux下动态链接库解决方案(一)

    1.c++无法直接调用用c写的动态链接库,如果调用的话可能需要用到一些交叉编译的知识: 2.在c++写的动态链接库无法被调用成功的反思: 在linux下,通常都是使用g++编译器("g++ ...

  8. 100个Github上Android开源库

    项目名称 项目简介 1. react-native 这个是 Facebook 在 React.js Conf 2015 大会上推出的基于 JavaScript 的开源框架 React Native, ...

  9. 【leetcode】triangle(easy)

    Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent n ...

  10. Eval绑定日期时,修改日期显示的格式

    我们使用DataList绑定数据的时候,需要将日期的格式做一个修改,比如绑定出来的日期格式是:“2015/8/12 0:0:0”,我们需要修改为“2015-8-12”,代码如下: <%#Eval ...