DNA repair 【HDU - 2457】【AC自动机+DP思路】

2023-10-26

题目链接


  开始肝这道题的时候也是冒了十足的勇气……呜呜呜,当时一直没发现,我有个地方写成了"s[i] - 'A'",怎么能这样用啊!毕竟只有A、C、G、T的说……呜呜呜…… QAQ

  然后讲一下,这道题的AC自动机的想法,还有DP的思路(我DP超菜…… 能过也是超神了……),我们在这用AC自动机来做的是去取状态,那么怎么取状态?我们先按照普遍的写法(AC自动机上建满路,下一步到达A、C、G、T全都要),然后去推前一刻的状态,用dp[0][0]表示0初始状态,然后去不断的往下递推待查询的那个模式串,要求是这样的,如果遇到的是病毒感染状态,那么就是不能要的状态,就不去更新它了(故除0初始状态以外,都赋为最大值点),如果目前不是病毒状态,我们去看,它可以改变成除了它以外的另外的状态(不一定是满的3个,因为有可能会从健康态变成病毒态),然后,若是改变原先的字符串,就要在之前的那一步上"+1",多了一步改变;若是发现是相等的,那么就不需要改变,去取最小值即可(因为可能存在不同的状态递推到这个点的状态)。

  然后AC自动机上怎么写?我们存储全部的状态,包括那些个不在字符串上的额外的状态,然后用一个静态数组去存它们,大致会有最多1000组的状态吧,把状态记录下来,然后在DP的时候去用到就可以了,主要是反映出前一刻的状态之用(此时的AC自动机的主要用途)。


#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdlib>
#include <ctime>
#include <unordered_map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 1005;
unordered_map<char, int> dir;
inline void pre_did() { dir['A'] = 0;   dir['C'] = 1;   dir['G'] = 2;   dir['T'] = 3; }
int N, num, dp[maxN][maxN], ans;
char virus[55], test[maxN];
struct node
{
    node *next[4];
    node *fail;
    int flag, id;
    node()
    {
        for(int i=0; i<4; i++) next[i] = NULL;
        fail = NULL;
        flag = id = 0;
    }
}tree[maxN];
node *root;
node *new_node()
{
    node *p = &tree[num];
    for(int i=0; i<4; i++) p->next[i] = NULL;
    p->fail = NULL;
    p->flag = 0;
    p->id = num++;
    return p;
}
void update(char *s)
{
    node *temp = root;
    int len = (int)strlen(s);
    for(int i=0; i<len; i++)
    {
        int x = dir[s[i]];
        if(temp->next[x] == NULL) temp->next[x] = new_node();
        temp = temp->next[x];
    }
    temp->flag = 1;
}
void build_fail()
{
    queue<node *> Q;
    Q.push(root);
    node *temp;
    while(!Q.empty())
    {
        temp = Q.front();   Q.pop();
        for(int i=0; i<4; i++)
        {
            if(temp->next[i])
            {
                if(temp == root) temp->next[i]->fail = root;
                else
                {
                    node *p = temp->fail;
                    while(p)
                    {
                        if(p->next[i]) { temp->next[i]->fail = p->next[i];  break; }
                        p = p->fail;
                    }
                    if(!p) temp->next[i]->fail = root;
                    if(temp->next[i]->fail->flag) temp->next[i]->flag = 1;
                }
                Q.push(temp->next[i]);
            }
            else temp->next[i] = (temp == root ? root : temp->fail->next[i]);
        }
    }
}
void AC_auto(char *s)
{
    ans = INF;  memset(dp, INF, sizeof(dp));
    dp[0][0] = 0;
    int len = (int)strlen(s);
    for(int i=0; i<len; i++)
    {
        for(int j=0; j<num; j++)
        {
            for(int k=0; k<4; k++)
            {
                if(tree[j].next[k]->flag) continue;
                int x = dir[s[i]];
                if(x == k)
                {
                    dp[i+1][tree[j].next[k]->id] = min(dp[i][j], dp[i+1][tree[j].next[k]->id]);
                }
                else
                {
                    dp[i+1][tree[j].next[k]->id] = min(dp[i][j] + 1, dp[i+1][tree[j].next[k]->id]);
                }
            }
        }
    }
    for(int i=0; i<num; i++) ans = min(ans, dp[len][i]);
    if(ans >= INF) ans = -1;
}
inline void init()
{
    num = 0;
    root = new_node();
}
int main()
{
    pre_did();
    int Cas = 0;
    while(scanf("%d", &N) && N)
    {
        init();
        for(int i=1; i<=N; i++)
        {
            scanf("%s", virus);
            update(virus);
        }
        build_fail();
        scanf("%s", test);
        AC_auto(test);
        printf("Case %d: %d\n", ++Cas, ans);
    }
    return 0;
}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

DNA repair 【HDU - 2457】【AC自动机+DP思路】 的相关文章

  • vs下载安装太慢的问题解决

    悔恨把当初 下载的vs给卸载了 如今下载80kb s折磨人 今天花了十来分钟终于知道怎么加快速度了 网上看了很多资料 最后整合如下 1 站长工具用这个网站查询所在的域名 download visualstudio microsoft com
  • Android13源码下载及全编译流程

    目录 一 源码下载 1 1 配置要求 1 1 1 硬件配置要求 1 1 2 软件要求 1 2 下载环境搭建 1 2 1 依赖安装 1 2 2 工具安装 1 2 3 git配置 1 2 4 repo配置 1 3 源码下载 1 3 1 明确下载
  • 光学成像原理之景深(Depth of Field)

    1 概述 先看两个例子 拍摄花 昆虫等照片时 背景拍的比较模糊 突出被拍物 但当拍摄纪念照 风景等照片时 却会把背景拍摄得和被拍对象一样清晰 这两者就是不同景深 前者为浅景深 拍摄聚焦到被拍物上 只能拍清一小段距离 被拍物前后的景色都被虚化

随机推荐

  • SpringCloud-Zuul服务网关与Ribbon负载均衡

    今天继续学习SpringCloud 上篇我们讲了 Eureka和服务提供者 消费者 这一篇针对服务网关和负载均衡详细说说 以下代码皆用最简单的代码示例 并非真正的业务代码 学习中用到的学习资料如下 文章 SpringCloud极简入门 视频
  • 我要进大厂第三讲:跳槽,如何选择一家公司

    我要进大厂第三讲 跳槽 如何选择一家公司 本文是我要进大厂第三讲 跳槽 如何选择一家公司 跳槽是每个程序员都会经历的 作为一个跳槽过好几次的人 对于跳槽这件事我还是有一定的发言权的 总结就一个字 真鸡儿累 如果新的岗位发展前景不错 也比较适
  • 效率优化之多轨数据传输

    项目效率优化是开发者避免不了的问题 最常见的方案是服务器升级性能优化 算法策略的优化 比如动态规划等 此次 笔者分享一种效率优化的方案 多轨道数据传输 拿insert2000条数据举例 2000tiao数据一条一条插入 我的电脑耗时大约16
  • Python 数据结构与算法,中文版请下载!

    数据结构作为计算机从业人员的必备基础 Java c 之类的语言有很多这方面的书籍 Python 相对较少 其中比较著名的一本 Python 数据结构与算法 所以我在学习的过程中将其翻译了中文版 希望对大家有点帮助 地址 github 地址
  • 2021美赛D题思路解析

    2021美赛D题思路解析 打完更 正在路上
  • hibernate.cfg.xml配置文件

  • UnityShader从入门到放弃(二)表面着色器和顶点、片元着色器

    1 表面着色器 表面着色器是Unity特有的一种着色器代码类型 表面着色器定义在SubShader中 表面着色器需要编写的代码量很少 Unity会自动处理一些细节 但是表面着色器的本质和顶点 片元着色器是一样的 当我们定义一个表面着色器的时
  • mysql对搜索结果多条记录的处理

    用游标 和WHILE可以遍历您的查询中的每一条记录并将要求的字段传给变量进行相应的处理 DECLARE A1 VARCHAR 10 A2 VARCHAR 10 A3 INT DECLARE CURSOR YOUCURNAME FOR SEL
  • QT富文本简单使用

    QT富文本简单使用 介绍 插入 遍历指定框架 遍历指定框架中所有文本块 包括子框架 介绍 富文本其实就是在一个编辑框内又输入文字又输入图片等各种东西 不仅仅是文字 qt自带的有QTextEdit 该类中有一个QTextDocument 一切
  • 实验10——摄像头实验

    实验十 摄像头实验 一 实验目的 利用ESP32 CAM开启摄像头 在网站上显示实时图像 二 实验内容 1 配置基本的开发环境 2 烧录代码 3 在网页上显示实时摄像 三 实验设备 1 ESP32 CAM发板 2 杜邦线 四 实验步骤 1
  • C++中实参形参传递、返回值产生的临时变量

    C 中实参形参传递 返回值产生的临时变量 C和C 中的副本机制 1 函数返回值产生的临时变量 2 实参形参传递过程中产生的临时变量 C和C 中的副本机制 函数的形参 return 都有副本机制 数组没有副本机制 为了节约内存 副本机制就会产
  • Java - XPath解析爬取内容

    maven依赖
  • npm install报错的几种解决办法

    1 可能是缓存问题 vscode新导入项目 使用npm i 安装包时 经常出现npm ERR code EINTEGRITY的问题 应该是npm本地的缓存造成的 1 删除package lock json文件 如果不想更改此文件 装完之后还
  • git问题error: remote origin already exists.

    1 先删除远程 Git 仓库 git remote rm origin 2 再添加远程 Git 仓库 git remote add origin https gitee com xx xxxx git 3 最后git push origin
  • Linux终端Tab提示忽略大小写

    1 在用户家目录下创建 inputrc 文件 touch inputrc 2 在该文件中输入以下内容 set completion ignore case on vi inputrc 输入set completion ignore case
  • 各种杂志投稿方式与评价

    导读 一 目录 1计算机应用研究 2 现代通信 3 火力与指挥控制 4系统仿真学报 5 宇航学报 6导弹与航天运载技术 7小型微型计算机系统 8计算机仿真 9自动化学报 10微计算机信息 11继电器 12电网技术 13传感器技术 14西北农
  • mybatis在insert时,实体类字段为null时,报错问题

    mybatis在insert时 实体类字段为null时 报错问题 在执行SQL时MyBatis会自动通过对象中的属性给SQL中参数赋值 它会自动将Java类型转换成数据库的类型 而一旦传入的是null它就无法准确判断这个类型应该是什么 就有
  • python基础5——正则、数据库操作

    文章目录 一 数据库编程 1 1 connect 函数 1 2 命令参数 1 3 常用语句 二 正则表达式 2 1 匹配方式 2 2 字符匹配 2 3 数量匹配 2 4 边界匹配 2 5 分组匹配 2 6 贪婪模式 非贪婪模式 2 7 标志
  • 【狂神】MySQl - 修改和删除数据库表字段

    1 修改和删除数据库表字段 测试表 CREATE TABLE teacher id INT 11 NOT NULL COMMENT 教师编号 name VARCHAR 100 NOT NULL COMMENT 教师名称 PRIMARY KE
  • DNA repair 【HDU - 2457】【AC自动机+DP思路】

    题目链接 开始肝这道题的时候也是冒了十足的勇气 呜呜呜 当时一直没发现 我有个地方写成了 s i A 怎么能这样用啊 毕竟只有A C G T的说 呜呜呜 QAQ 然后讲一下 这道题的AC自动机的想法 还有DP的思路 我DP超菜 能过也是超神