HDU2457 DNA repair(AC自动机+DP)

题目一串DNA最少需要修改几个基因使其不包含一些致病DNA片段。

这道题应该是AC自动机+DP的入门题了,有POJ2778基础不难写出来。

dp[i][j]表示原DNA前i位(在AC自动机上转移i步)且后缀状态为AC自动机结点j的最少需要修改的基因数

转移我为人人型,从dp[i][j]向ATCG四个方向转移到dp[i+1][j‘],如果结点被标记包含致病基因就不能转移。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<queue>
 4 using namespace std;
 5 #define INF (1<<30)
 6 int tn,ch[1111][4],fail[1111],idx[128];
 7 bool flag[1111];
 8 void insert(char *s){
 9     int x=0;
10     for(int i=0; s[i]; ++i){
11         int y=idx[s[i]];
12         if(ch[x][y]==0) ch[x][y]=++tn;
13         x=ch[x][y];
14     }
15     flag[x]=1;
16 }
17 void init(){
18     memset(fail,0,sizeof(fail));
19     queue<int> que;
20     for(int i=0; i<4; ++i){
21         if(ch[0][i]) que.push(ch[0][i]);
22     }
23     while(!que.empty()){
24         int x=que.front(); que.pop();
25         for(int i=0; i<4; ++i){
26             if(ch[x][i]) que.push(ch[x][i]),fail[ch[x][i]]=ch[fail[x]][i];
27             else ch[x][i]=ch[fail[x]][i];
28             flag[ch[x][i]]|=flag[ch[fail[x]][i]];
29         }
30     }
31 }
32 int d[1111][1111];
33 int main(){
34     idx[‘A‘]=0; idx[‘G‘]=1; idx[‘C‘]=2; idx[‘T‘]=3;
35     char str[1111];
36     int n,t=0;
37     while(~scanf("%d",&n) && n){
38         tn=0;
39         memset(ch,0,sizeof(ch));
40         memset(flag,0,sizeof(flag));
41         while(n--){
42             scanf("%s",str);
43             insert(str);
44         }
45         init();
46         scanf("%s",str+1);
47         n=strlen(str+1);
48         for(int i=0; i<=n; ++i){
49             for(int j=0; j<=tn; ++j) d[i][j]=INF;
50         }
51         d[0][0]=0;
52         for(int i=0; i<n; ++i){
53             for(int j=0; j<=tn; ++j){
54                 if(d[i][j]==INF || flag[j]) continue;
55                 for(int k=0; k<4; ++k){
56                     if(flag[ch[j][k]]) continue;
57                     if(idx[str[i+1]]==k) d[i+1][ch[j][k]]=min(d[i+1][ch[j][k]],d[i][j]);
58                     else d[i+1][ch[j][k]]=min(d[i+1][ch[j][k]],d[i][j]+1);
59                 }
60             }
61         }
62         int res=INF;
63         for(int i=0; i<=tn; ++i) res=min(res,d[n][i]);
64         if(res==INF) printf("Case %d: %d\n",++t,-1);
65         else printf("Case %d: %d\n",++t,res);
66     }
67     return 0;
68 }
时间: 2024-12-28 09:41:09

HDU2457 DNA repair(AC自动机+DP)的相关文章

POJ 3691 DNA repair AC自动机 + DP

题意:给你只包含‘A’,‘G’,‘T’,‘C’四个字母的n个模板串和1个文本串,问你文本串改变多少个字符就可以使得文本串中没有一个模板串 解题思路: 我们可以知道  dp[i][j] 为文本串到 第i 个字符  AC自动机状态为j的最少的变换次数(这里为什么要用AC自动机,因为end数组可以记录哪一个状态是结束的,而且处理以后可以知道那些后缀等于前缀--也就是不能到达,因为如果能够到达的话那么状态更新就会产生错误.),这样dp即可 解题代码: 1 // File Name: temp.cpp 2

HDU 2457 DNA repair AC自动机 + dp

http://acm.hdu.edu.cn/showproblem.php?pid=2457 首先把病毒串保存一下,然后对于每一个trie上的节点,跑一发AC自动机,建立一个trie图. 建立的时候,对应做一些修改. 比如,现在建立成了这个样子. 如果he是一个病毒串,那么应该相对应的,把she那个he的位置,标志上,它也是病毒串,也就是不能转移到这一个状态. 这个可以在buildfail的时候对应修改. dp, 设dp[i][j],表示处理到字符串的第i个,走到了AC自动机的第j个节点,变成了

POJ 3691 &amp; 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: 2000MS   Memory Limit: 65536K Total Submissions: 5690   Accepted: 2669 Description Biologists finally invent techniques of repairing DNA that contain

poj3691--DNA repair(AC自动机+dp)

DNA repair Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 5743   Accepted: 2693 Description Biologists finally invent techniques of repairing DNA that contains segments causing kinds of inherited diseases. For the sake of simplicity, a

hdu2457---DNA repair(AC自动机+dp)

Problem Description Biologists finally invent techniques of repairing DNA that contains segments causing kinds of inherited diseases. For the sake of simplicity, a DNA is represented as a string containing characters 'A', 'G' , 'C' and 'T'. The repai

HDU 2457 DNA repair (AC自动机 + DP)

题目链接:DNA repair 解析:给出n个致病DNA序列,给一段DNA片段,问最少修改多少个碱基才能修复这段DNA序列中的所有致病序列. AC自动机 + DP. 将n个致病DNA序列构成一个自动机. 令DP[i][j]表示长度为i走到节点j是所需改变的最少个数. 状态转移时,枚举下一步所有可能的碱基,然后判断该碱基是否达到匹配状态,若能,则安全转移,继续枚举下一个碱基:否则在不匹配的前提下,看该碱基加入之后是否跟上一状态相同,若不同,则需修复,即计数加一.若相同,直接转移即可.然后选择其中最

hdu 2457 AC自动机+dp

DNA repair Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2004    Accepted Submission(s): 1085 Problem Description Biologists finally invent techniques of repairing DNA that contains segments c

HDU3341 Lost&#39;s revenge(AC自动机+DP)

题目是给一个DNA重新排列使其包含最多的数论基因. 考虑到内存大概就只能这么表示状态: dp[i][A][C][G][T],表示包含各碱基个数为ACGT且当前后缀状态为自动机第i的结点的字符串最多的数论基因数 其中ACGT可以hash成一个整数(a*C*G*T+c*G*T+g*T+T),这样用二维数组就行了,而第二维最多也就11*11*11*11个. 接下来转移依然是我为人人型,我是丢进一个队列,用队列来更新状态的值. 这题果然挺卡常数的,只好手写队列,最后4500msAC,还是差点超时,代码也

Hdu 3341 Lost&#39;s revenge (ac自动机+dp+hash)

题目大意: 给出很多个DNA串,每一个串的价值为1,最后给出一个长串,要你重新排列最后的串使之它所有的子串的权值和最大. 思路分析: 最先容易想到的思路就是搜!管她3721..直接一个字符一个字符的码,然后在AC自动机上判断最后的权值.TLE哟. 然后发现搜过不去,那就dp咯.再容易想到的就是dp[i][a][b][c][d] 表示此时遍历AC自动机的节点在i,然后构成了a个A,b个G,c个C,d个T的权值. 再一看内存,500*40*40*40*40...然后...就没有然后了 再想,因为它说