题意 : 给出 n 个病毒串,最后再给出一个主串,问你最少改变主串中的多少个单词才能使得主串中不包含任何一个病毒串

分析 : 做多了AC自动机的题,就会发现这些题有些都是很套路的题目。在构建 Trie 图的时候给病毒串末尾打上标记,最后定义DP[i][j] = 长度为 i 的串在 j 这个状态节点最少改变数使得其不包含病毒串,则状态转移方程

if(Trie[k]不是被标记的病毒节点) DP[i+1][j] = min( DP[i+1][j], DP[i][k] + (mp[S[i]] != k) )

k 为 j 节点的四个下一状态,转到"ATGC"其中一个,而mp[]作用是把"ATGC"转为0、1、2、3

DP的初始状态为 DP[0][0] = 0,DP[0~len][0~节点数] = INF

具体的看代码即可

#include<queue>
#include<stdio.h>
#include<string.h>
using namespace std;

;
;
const int INF = 0x3f3f3f3f;
];

struct Aho{
    struct StateTable{
        int Next[Letter];
        int fail, flag;
    }Node[Max_Tot];
    int Size;
    queue<int> que;

    inline void init(){
        while(!que.empty()) que.pop();
        memset(Node[].Next, , ].Next));
        Node[].fail = Node[].flag = ;
        Size = ;
    }

    inline void insert(char *s){
        ;
        ; s[i]; i++){
            int idx = mp[s[i]];
            if(!Node[now].Next[idx]){
                memset(Node[Size].Next, , sizeof(Node[Size].Next));
                Node[Size].fail = Node[Size].flag = ;
                Node[now].Next[idx] = Size++;
            }
            now = Node[now].Next[idx];
        }
        Node[now].flag = ;
    }

    inline void BuildFail(){
        Node[].fail = ;
        ; i<Letter; i++){
            ].Next[i]){
                Node[Node[].Next[i]].fail = ;
                que.push(Node[].Next[i]);
            }].Next[i] = ;///必定指向根节点
        }
        while(!que.empty()){
            int top = que.front(); que.pop();
            ;
            ; i<Letter; i++){
                int &v = Node[top].Next[i];
                if(v){
                    que.push(v);
                    Node[v].fail = Node[Node[top].fail].Next[i];
                }else v = Node[Node[top].fail].Next[i];
            }
        }
    }
}ac;
];
][];

int main(void)
{
    mp[,
    mp[,
    mp[,
    mp[;
    ;
    while(~scanf("%d", &n) && n){
        ac.init();
        ; i<n; i++){
            scanf("%s", S);
            ac.insert(S);
        }
        ac.BuildFail();
        scanf("%s", S);
        int len = strlen(S);

        ; i<=len; i++)
            ; j<=ac.Size; j++)
                dp[i][j] = ;

        dp[][] = ;

        ; i<len; i++){
            ; j<ac.Size; j++){
                ){
                    ; k<; k++){
                        ;
                        int newj = ac.Node[j].Next[k];
                        if(!ac.Node[newj].flag){
                            dp[newi][newj] = min(dp[newi][newj],
                                                 dp[i][j] + (k != mp[S[i]]) );
                        }
                    }
                }
            }
        }

        ;
        ; i<ac.Size; i++)
            ans = min(ans, dp[len][i]);

        printf("Case %d: ", Case++);
        ) printf("%d\n", ans);
        else puts("-1");
    }
    ;
}

POJ 3691 DNA repair ( Trie图 && DP )的更多相关文章

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

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

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

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

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

    DNA repair Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4815   Accepted: 2237 Descri ...

  4. poj 3691 DNA repair(AC自己主动机+dp)

    DNA repair Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 5877   Accepted: 2760 Descri ...

  5. POJ 2778 DNA Sequence ( Trie图、矩阵快速幂 )

    题意 : 给出一些病毒串,问你由ATGC构成的长度为 n 且不包含这些病毒串的个数有多少个 分析: 我们先分析Tire 图的结构 : Trie图是在AC自动机的原型上增添边使得状态可以快速转移,标记危 ...

  6. POJ 3691 DNA repair (DP+字符串)

    题意:给出nn(1≤n≤50,1≤n≤50) 个病毒DNA序列,长度均不超过20.现在给出一个长度不超过1000的字符串,求至少要更换多少个字符, 才能使这个字符串不包含这些DNA序列. 析:利用前缀 ...

  7. POJ 3691 DNA repair 基于AC自己主动机DP

    dp[i][j] 它表示的长度 i 下游前缀 j 更改节点的最小数量. 很清楚dp[0][0] = 0; dp[ i ][ j ] = min(dp[ i ][ j ],dp[i-1][k] + (j ...

  8. [poj 3691]DNA repair

    好久没刷 poj 了,今天练习 AC 自动机时去水了一发喵~ 在 poj 上 A 题的感觉并没有 BZOJ 上那么愉悦,准确的说是痛不欲生 真是应了那句老话,你再慢也有比你慢的,你再快也有比你快的…… ...

  9. 【Trie图+DP】BZOJ1030[JSOI2007]-文本生成器

    [题目大意] 给出单词总数和固定的文章长度M,求出至少包含其中一个单词的可能文章数量. [思路] 对于至少包含一个的类型,我们可以考虑补集.也就是等于[总的文章可能性总数-不包含任意一个单词的文章总数 ...

随机推荐

  1. centos7 主从dns配置 bind服务

    一,配置前请先关闭防火墙selinux 防火墙关闭方法,参见上一篇文章. setenforce 0    #临时关闭 修改/etc/selinux/config 文件  将SELINUX=enforc ...

  2. CSS3——提示工具 图片廓 图像透明 图像拼接技术 媒体类型 属性选择器

    提示工具 提示框在鼠标移动到特定的元素上显示 设置提示框的位置 给提示框添加箭头 提示框的淡入效果 提示框美化 图片廓 响应式图片廓 图像透明 创建透明图像——悬停效果 ———鼠标放置后———> ...

  3. AngularJS——基础小知识(一)

    $time0ut :定时器 $rootscope :全局的 $scope : 局部的作用域:   它下面的方法: $scope.$watch $scope.$apply   1)$scope.$wat ...

  4. Linux常用命令基础

    linux 常用指令 基础命令 宿主目录 目录结构 文件管理 目录管理 用户管理 别名管理 压缩包管理 网络设置 shell技巧 帮助方法 /表示根目录 ~表示家目录 软件的安装(光盘中的软件呢): ...

  5. Fedora添加软件桌面快捷方式

    以下以添加Eclipse为例 在桌面上新建Eclipse.desktop 文件,向其写入如下代码 [Desktop Entry] Name=Eclipse Comment=用Eclipse开发 Exe ...

  6. 20170309工作笔记--------如何用好dialog,想变什么样就变成什么样

    (1)首先自定义一个dialog的div,并且写内容 (2)运用相应的代码进行控制,弹出dialog $(".tel").click(function() { $("#d ...

  7. TApplication,TForm,TControl,TComponent,TWinControl研究(博客索引)good

    TApplication,TForm,TControl,TComponent,TWinControl研究 http://blog.csdn.net/suiyunonghen/article/detai ...

  8. BZOJ 5317: [Jsoi2018]部落战争

    传送门 写出式子,若存在 $a \in A$,$b \in B$,使得 $b+v=a$,那么此方案会产生冲突 即存在 $a \in A$,$b \in B$,使得 $v=a+(-b)$,设 $C=A+ ...

  9. http参数传递方式

    url传参 这种在各种method(get,post,delete,put)都能使用,解析速度快 body体中的参数 application/x-www-form-urlencoded 这应该是最常见 ...

  10. windows下挂载NFS共享目录

    1.在打开或关闭Windows功能中,选择安装NFS客户端 2.在命令行中,输入“mount \\172.24.184.31\data x:\”,输入mount查看详细挂载参数(注意此时uid.gid ...