给定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;
}

  

最新文章

  1. jQuery 简介和安装
  2. 【mysql】利用Navicat for MySQL的使用
  3. ASP.NET Excel 导入 Oracle 方法2
  4. DB面试题
  5. SQL Server 地理数据库中的系统表
  6. Json 的日期格式转换成DateTime
  7. Js使用word书签填充内容
  8. (二)《Java编程思想》——t h i s 关键字
  9. 一个web初学者的笔记总结
  10. ASP.NET - 使用 XML
  11. GIMP也疯狂之动态图的制作(二)
  12. eclipse安装和中文汉化,以及配置
  13. How hacker do IT: Tricks Tools and Techniques (翻译)
  14. Java开发笔记(十二)布尔变量论道与或非
  15. 2018-2019-2 《网络对抗技术》Exp2 后门原理与应用 20165211
  16. LG4071 [SDOI2016]排列计数
  17. 【ZZ】C++11之统一初始化语法 | 桃子的博客志
  18. Ionic APP 热更新 之 产品发布状态下的热更新搭建,去local-dev-addon插件
  19. MySQL运维开发相关的所有工具
  20. 【BZOJ】【2878】【NOI2012】迷失游乐园

热门文章

  1. 7.在AngularJS视图中实现指令
  2. nginx 下 bootstrap fa 字体异常问题
  3. PhpExcel笔记,phpExcel中文帮助手册
  4. SQL Server数据库主键与索引的几点区别
  5. Oracle java.sql.SQLException: 数字溢出
  6. WPS Office文档未保存怎么恢复
  7. ACM/ICPC 之 BFS(离线)+康拓展开 (HDU1430-魔板)
  8. [NSURLSession/Delegate]用Post方式获取网络数据并把数据显示到表格
  9. Greedy:Paint Color(AOJ 0531)
  10. ajax 删除一条数据