zoukankan      html  css  js  c++  java
  • DNA repair

    题目大意:给你N个DNA的串,也就是至包含'A','T','G','C'四种碱基的,这些给定的串都是带有遗传病的,然后给你一个不会超过1000的串,问你至少几个地方才能让这个串不包含遗传病,如果不论怎么修改都没用,输出'-1'

     

    分析:用dp[Ni][nNode],表示长度为i时候到达第n个节点修改的最小次数,然后统计最后一层次最小次数就行了。

     

    代码如下:

    =============================================================================================================================

    #include<iostream>
    #include<algorithm>
    #include<stdio.h>
    #include<string.h>
    #include<queue>
    using namespace std;
    
    const int MAXN = 1007;
    const int MAXM = 57;
    const int MaxSon = 4;
    const int oo = 1e9+7;
    
    int dp[MAXN][MAXN];
    
    struct Ac_Trie
    {
        int next[MAXN][MaxSon];
        int Fail[MAXN], End[MAXN];
        int cnt, root;
    
        int newnode()
        {
            for(int i=0; i<MaxSon; i++)
                next[cnt][i] = -1;
            Fail[cnt] = End[cnt] = false;
    
            return cnt++;
        }
        void InIt()
        {
            cnt = 0;
            root = newnode();
        }
        int Find(char ch)
        {
            if(ch == 'A')return 0;
            if(ch == 'T')return 1;
            if(ch == 'G')return 2;
    
            return 3;
        }
        void Insert(char s[])
        {
            int now = root;
    
            for(int i=0; s[i]; i++)
            {
                int k = Find(s[i]);
    
                if(next[now][k] == -1)
                    next[now][k] = newnode();
                now = next[now][k];
            }
    
            End[now] = true;
        }
        void GetFial()
        {
            queue<int>Q;
            int now = root;
    
            for(int i=0; i<MaxSon; i++)
            {
                if(next[now][i] == -1)
                    next[now][i] = root;
                else
                {
                    Fail[next[now][i]] = root;
                    Q.push(next[now][i]);
                }
            }
    
            while(Q.size())
            {
                now = Q.front();
                Q.pop();
    
                for(int i=0; i<MaxSon; i++)
                {
                    if(next[now][i] == -1)
                        next[now][i] = next[Fail[now]][i];
                    else
                    {
                        Fail[next[now][i]] = next[Fail[now]][i];
                        Q.push(next[now][i]);
                    }
                }
    
                End[now] |= End[Fail[now]];
            }
        }
    };
    Ac_Trie ac;
    
    
    int main()
    {
        int N, t=1;
    
        while(scanf("%d", &N), N)
        {
            char s[MAXN];
            ac.InIt();
    
            for(int i=0; i<N; i++)
            {
                scanf("%s", s);
                ac.Insert(s);
            }
            ac.GetFial();
    
            scanf("%s", s+1);
            N = strlen(s);
    
            for(int i=0; i<=N; i++)
            for(int j=0; j<ac.cnt; j++)
                dp[i][j] = oo;
    
            dp[0][0] = 0;
    
            for(int i=0; i<N-1; i++)
            for(int j=0; j<ac.cnt; j++)
            for(int k=0; k<4; k++)
            {
                int w = dp[i][j];
                int next = ac.next[j][k];
    
                if(ac.End[next])continue;
    
                if(ac.Find(s[i+1]) != k)
                    w++;
    
                if(dp[i+1][next] > w)
                    dp[i+1][next] = w;
            }
    
            int Min = oo;
    
            for(int i=0; i<ac.cnt; i++)
                Min = min(Min, dp[N-1][i]);
    
            if(Min == oo)
                Min = -1;
    
            printf("Case %d: %d
    ", t++, Min);
        }
    
        return 0;
    }
  • 相关阅读:
    发送邮件程序
    T-SQL存储过程、游标
    GPS经纬度换算成XY坐标
    开博了
    你应该知道的 50 个 Python 单行代码
    想提升java知识的同学请进
    adb工具包使用方法
    红米note3刷安卓原生
    hadoop 使用和javaAPI
    django学习——url的name
  • 原文地址:https://www.cnblogs.com/liuxin13/p/4760287.html
Copyright © 2011-2022 走看看