题意 : 给出 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. Scala的集合框架

    1.元组 定义方式:val tp=("nana',1,1.1) 特点:集合中的数据可以是不同类型的 最多只能放22个元素 取值:通过角标取值,这里的角标是从1开始的,元组名称._角标   t ...

  2. 测试需要了解的技术之基础篇四__UI自动化测试体系

    UI自动化测试体系 1.Andriod 自动化测试:Appium 环境安装与架构介绍.Appium Desktop用例录制.Appium测试用例流程.元素定位方法 IA/AID/XPATH/UISel ...

  3. Java回调机制的理解

    用一句话讲明回调机制就是,在A类里面拥有一个类B的对象,调用B类的某个方法并把自身引用传入,在B类的这个方法里面又通过传进来的A的引用来调用A类的某个方法(这个最后调用的A类的方法就叫做回调方法). ...

  4. ZABBIX_PROXy

    ProxyMode=0 Server=172.19.30.50 ServerPort=10051 Hostname=172.17.26.102 ListenPort=10051 LogFile=/va ...

  5. 【Python基础】_1 Python简介

    1 Python简介 Python是一种计算机程序设计语言.是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越来越多被用于独立的.大型项 ...

  6. Linux操作系统目录一览表

    / // 根目录 /bin //存放必要的命令 比如ls.cp.mkdir等命令 /boot //存放内核以及启动所需的文件 /dev //存放硬件设备文件 比如声卡.磁盘.光驱 /etc //存放系 ...

  7. 【Linux 环境搭建】Ubuntu下安装tftp

    1.安装软件    sudo apt-get install tftp-hpa tftpd-hap xinetd 2.修改配置文件    sudo vim /etc/default/tftpd-hpa ...

  8. [转帖]安全公告【安全公告】CVE-2019-0708远程桌面服务远程代码执行漏洞

    [安全公告]CVE-2019-0708远程桌面服务远程代码执行漏洞 https://www.landui.com/help/nshow-9716.html 漏洞层出不穷 漏洞信息: 2019年5月14 ...

  9. 牛客练习赛51 C 勾股定理

    链接:https://ac.nowcoder.com/acm/contest/1083/C 题目描述 给出直角三角形其中一条边的长度n,你的任务是构造剩下的两条边,使这三条边能构成一个直角三角形. 输 ...

  10. (Windows)Python第三方库手动安装教程(以lxml库为例)

    案例前提:已安装Python 已安装pip 1.进入官网https://www.lfd.uci.edu/~gohlke/pythonlibs/,搜索lxml库,下载到本地(放到Python目录下的Sc ...