• HDU 2457 DNA repair AC自动机+dp


    调了1天,居然是我的AC自动机板子有问题。。。
    这个板子是真的繁琐
    8/27/21:16 已更新简洁版本

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<map>
    #include<queue>
    #include<vector>
    #include<string>
    #include<fstream>
    using namespace std;
    #define rep(i, a, n) for(int i = a; i <= n; ++ i);
    #define per(i, a, n) for(int i = n; i >= a; -- i);
    typedef long long ll;
    const int N = 1e3 + 5;
    const int mod = 998244353;
    const double Pi = acos(- 1.0);
    const int INF = 0x3f3f3f3f;
    const int G = 3, Gi = 332748118;
    ll qpow(ll a, ll b) { ll res = 1; while(b){ if(b & 1) res = (res * a) % mod; a = (a * a) % mod; b >>= 1;} return res; }
    ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
    bool cmp(int a, int b){return a > b;}
    //
    
    map<char, int>mp;
    struct Aho{
        int nxt[N][30] ,fail[N], mark[N];
        int size;
        
        queue<int> que;
        void init(){
            while(que.size()) que.pop();
            memset(nxt, 0, sizeof(nxt));
            memset(fail, 0, sizeof(fail));
            memset(mark, 0, sizeof(mark));
            size = 0;
        }
        
        //建立trie树
        void Insert(char *S){
            int n = strlen(S);
            int now = 0;
            for(int i = 0; i < n; ++ i){
                int id = mp[S[i]];
                if(!nxt[now][id]) nxt[now][id] = ++ size;
                now = nxt[now][id];
            }
            mark[now] = 1;
        }
        
        //建立fail指针
        void Build(){
            fail[0] = -1;
            for(int i = 0; i < 4; ++ i){
                if(nxt[0][i]) que.push(nxt[0][i]);
            }
            
            while(que.size()){
                int u = que.front(); que.pop();
                for(int j = 0; j < 4; ++ j){
                    int v = nxt[u][j];
                    if(!v) nxt[u][j] = nxt[fail[u]][j];
                    else{
                        que.push(v);
                        fail[v] = nxt[fail[u]][j];
                        mark[v] |= mark[fail[v]];
                    }
                }
            }
        }
    }aho;
    
    
    int T,n;
    char s[N];
    int dp[N][N], res, Case = 0;
    
    int solve(){
        n = strlen(s + 1);
        memset(dp, 0x3f, sizeof(dp));
        dp[0][0] = 0;
        for(int i = 1; i <= n; ++ i){
            for(int j = 0; j <= aho.size; ++ j){
                for(int k = 0; k < 4; ++ k){
                    int v = aho.nxt[j][k];
                    if(aho.mark[v]) continue;
                    dp[i][v] = min(dp[i][v], dp[i - 1][j] + (mp[s[i]] != k)); 
                }
            }
        }
        
        res = INF;
        for(int i = 0; i <= aho.size; ++ i){
            res = min(res, dp[n][i]);
        }
        if(res == INF) res = -1;
        return res;
    }
    
    int main()
    {
        mp['A'] = 0, mp['T'] = 1, mp['G'] = 2, mp['C'] = 3; 
        while(~scanf("%d",&n) && n){
            aho.init();
            for(int i = 1; i <= n; ++ i){
                scanf("%s",s);
                aho.Insert(s);
            }
            aho.Build();
            scanf("%s",s + 1);
            printf("Case %d: %d
    ",++ Case, solve());
        }
        return 0;
    }
    
    
  • 相关阅读:
    【题解】SDOI2015序列统计
    【合集】有标号的DAG图计数(合集)
    【题解】有标号的DAG计数4
    【题解】有标号的DAG计数3
    【题解】有标号的DAG计数2
    【题解】有标号的DAG计数1
    【题解】歌唱王国(概率生成函数+KMP)+伦讲的求方差
    【题解】CTS2019珍珠(二项式反演+卷积)
    【题解】餐巾计划问题
    【题解】数字梯形问题
  • 原文地址:https://www.cnblogs.com/A-sc/p/13572111.html
Copyright © 2020-2023  润新知