[poj 3691]DNA repair
好久没刷 poj 了,今天练习 AC 自动机时去水了一发喵~
在 poj 上 A 题的感觉并没有 BZOJ 上那么愉悦,准确的说是痛不欲生
真是应了那句老话,你再慢也有比你慢的,你再快也有比你快的……
跪求那些 0ms 的代码啊,还有那么多人都只跑了 32ms 啊!!
果然还是我太弱了吗?一定是我还太弱了 TAT
一道裸裸的 AC 自动机上 dp
令 dp[i][j] 表示母串的前 i 个字母遍历 AC 自动机,使之到达 j 节点,至少要修改多少个字母
dp[i+1][k]=min(dp[i+1][k], dp[i][j]+CHAR(j->k)!=s[i]) { k 不为匹配点}
CHAR(j->k) 是指在 AC 自动机上从点 j 转移到点 k 的边时经过的字母
答案就是 min{dp[len(s)][i]} 了喵~
我才不会说我是来晒我的 AC 自动机代码的呢~ (虽然被 poj 的各大神犇搞得一点优越感都没有……)
- #include <cstdio>
- #include <cstring>
- const int inf=0x3F3F3F3F;
- const int sizeOfText=;
- const int sizeOfType=;
- const int sizeOfMemory=;
- namespace trieDfa
- {
- struct node
- {
- int idx;
- bool end;
- node * fail;
- node * ch[sizeOfType];
- };
- node * dfa;
- node memory[sizeOfMemory]; int port;
- node * E[sizeOfMemory];
- inline node * newnode()
- {
- node * ret=memory+port;
- E[ret->idx=port++]=ret;
- ret->end=;
- ret->fail=NULL;
- memset(ret->ch, , sizeof(ret->ch));
- return ret;
- }
- inline void clear() {port=; dfa=newnode();}
- inline int ord(char ch)
- {
- switch (ch)
- {
- case 'A':return ;
- case 'G':return ;
- case 'C':return ;
- case 'T':return ;
- }
- }
- inline void insert(char * s)
- {
- int len=strlen(s);
- node * t=dfa;
- for (int i=;i<len;i++)
- {
- if (!t->ch[ord(s[i])]) t->ch[ord(s[i])]=newnode();
- t=t->ch[ord(s[i])];
- }
- t->end=;
- }
- inline void buildDfa()
- {
- static node * queue[sizeOfMemory];
- int l=, r=;
- dfa->fail=dfa;
- for (int i=;i<sizeOfType;i++)
- if (!dfa->ch[i]) dfa->ch[i]=dfa;
- else dfa->ch[i]->fail=dfa, queue[r++]=dfa->ch[i];
- for ( ;l<r; )
- {
- node * u=queue[l++];
- u->end|=u->fail->end;
- for (int i=;i<sizeOfType;i++)
- if (u->ch[i])
- {
- u->ch[i]->fail=u->fail->ch[i];
- queue[r++]=u->ch[i];
- }
- else
- u->ch[i]=u->fail->ch[i];
- }
- }
- }
- using namespace trieDfa;
- int cases, n;
- char str[sizeOfText];
- int f[sizeOfText][sizeOfMemory];
- inline int min(int x, int y) {return x<y?x:y;}
- inline int dp(char * );
- int main()
- {
- for (scanf("%d", &n);n;scanf("%d", &n))
- {
- clear();
- for (int i=;i<=n;i++)
- {
- scanf("%s", str);
- insert(str);
- }
- buildDfa();
- scanf("%s", str);
- printf("Case %d: %d\n", ++cases, dp(str));
- }
- return ;
- }
- inline int dp(char * s)
- {
- int len=strlen(s);
- int ret=inf;
- memset(f, inf, sizeof(f));
- f[][]=;
- for (int i=;i<len;i++)
- for (int j=;j<port;j++)
- for (int k=;k<sizeOfType;k++)
- if (!E[j]->ch[k]->end)
- f[i+][E[j]->ch[k]->idx]=min(f[i+][E[j]->ch[k]->idx], f[i][j]+(ord(s[i])!=k));
- for (int i=;i<port;i++) ret=min(ret, f[len][i]);
- return ret==inf?-:ret;
- }
本傻装B系列
[poj 3691]DNA repair的更多相关文章
- POJ 3691 DNA repair (DP+AC自动机)
DNA repair Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4815 Accepted: 2237 Descri ...
- poj 3691 DNA repair(AC自己主动机+dp)
DNA repair Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 5877 Accepted: 2760 Descri ...
- HDU 2457/POJ 3691 DNA repair AC自动机+DP
DNA repair Problem Description Biologists finally invent techniques of repairing DNA that contains ...
- POJ 3691 DNA repair (DP+字符串)
题意:给出nn(1≤n≤50,1≤n≤50) 个病毒DNA序列,长度均不超过20.现在给出一个长度不超过1000的字符串,求至少要更换多少个字符, 才能使这个字符串不包含这些DNA序列. 析:利用前缀 ...
- POJ 3691 DNA repair(AC自动机+DP)
题目链接 能AC还是很开心的...此题没有POJ2778那么难,那个题还需要矩阵乘法,两个题有点相似的. 做题之前,把2778代码重新看了一下,回忆一下当时做题的思路,回忆AC自动机是干嘛的... 状 ...
- 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 ...
- POJ 3691 DNA repair ( Trie图 && DP )
题意 : 给出 n 个病毒串,最后再给出一个主串,问你最少改变主串中的多少个单词才能使得主串中不包含任何一个病毒串 分析 : 做多了AC自动机的题,就会发现这些题有些都是很套路的题目.在构建 Trie ...
- POJ 3691 DNA Sequence (AC自动机 + 矩阵 有bug,待修改)
DNA Sequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9889 Accepted: 3712 Desc ...
- POJ 3691 & HDU 2457 DNA repair (AC自己主动机,DP)
http://poj.org/problem?id=3691 http://acm.hdu.edu.cn/showproblem.php?pid=2457 DNA repair Time Limit: ...
随机推荐
- Visual Studio环境色调配色
据说对眼睛有好处的色调配色 vs 色调rgb 199,240,214 色调为84,饱和度为91,亮度为205 色调为85,饱和度为123,亮度205: “色调”由160更改为75-85之间——> ...
- PHP ceil() 函数
定义和用法 ceil() 函数向上舍入为最接近的整数. 语法 ceil(x) 参数 描述 x 必需.一个数. 说明 返回不小于 x 的下一个整数,x 如果有小数部分则进一位.ceil() 返回的类型仍 ...
- windows下将磁盘脱机,并在"我的电脑"下显示
方案一: .右键单击"我的电脑". 2.打开:管理-磁盘管理. 3.在右边出现的磁盘分区里,你想隐藏的分区上右键单击“更改驱动器名和路径”. 4.出现一个对话框,点击“删除”. 5 ...
- poj2649 数论
//Accepted 420K 16MS //考虑 0和n! does not divide // 1和0! divides #include <cstdio> #include < ...
- ACM - 概率、期望题目 小结(临时)
概率DP求期望大多数都是全期望公式的运用.主要思考状态空间的划分以及状态事件发生的概率.问题可以分为无环和有环两类.无环一类多数比较简单,可以通过迭代或者记忆化搜索完成.有环一类略复杂,可以通过假设方 ...
- 如何由Height Map生成Normal Map
转自:http://www.cnblogs.com/cxrs/archive/2009/11/01/1594155.html Nvidia和ATI都有相应的工具把Heightmap转成NormalMa ...
- System.out.println()输出到指定文件里
public static void main(String[] args) throws Exception{ String str = "abcd"; PrintStream ...
- __toString()与__call()
__toString()适用于直接输出类,用此方法,可以避免出错:__call()适用于使用类当中没有定义的函数(方法) <!DOCTYPE html> <html> < ...
- python3爬虫再探之豆瓣影评数据抓取
一个关于豆瓣影评的爬虫,涉及:模拟登陆,翻页抓取.直接上代码: import re import time import requests import xlsxwriter from bs4 imp ...
- IOS 作业项目(3) 霓虹灯效果
先上效果图 #import "CHViewController.h"@interface CHViewController (){ int i; int j;}@pro ...