zoukankan      html  css  js  c++  java
  • hdu2457

    AC自动机+DP

    #include <cstdio>
    #include <queue>
    #include <cstring>
    using namespace std;
    
    #define D(x) 
    
    const int MAX_D_LEN = 25;
    const int MAX_LEN = 1005;
    const int MAX_N = 55;
    const int MAX_CHILD_NUM = 4;
    const int MAX_NODE_NUM = MAX_N * MAX_D_LEN;
    const int INF = 0x3f3f3f3f;
    
    char dna[MAX_LEN];
    
    struct Trie
    {
        int next[MAX_NODE_NUM][MAX_CHILD_NUM];
        int fail[MAX_NODE_NUM];
        bool disease[MAX_NODE_NUM];
        int node_cnt;
        bool vis[MAX_NODE_NUM]; //set it to false
        int root;
        int dp[MAX_LEN][MAX_NODE_NUM];
    
        void init()
        {
            node_cnt = 0;
            root = newnode();
            memset(vis, 0, sizeof(vis));
        }
    
        int newnode()
        {
            for (int i = 0; i < MAX_CHILD_NUM; i++)
                next[node_cnt][i] = -1;
            disease[node_cnt++] = false;
            return node_cnt - 1;
        }
    
        int get_id(char a)
        {
            if (a == 'A')
                return 0;
            if (a == 'T')
                return 1;
            if (a == 'C')
                return 2;
            return 3;
        }
    
        void insert(char buf[])
        {
            int now = root;
            for (int i = 0; buf[i]; i++)
            {
                int id = get_id(buf[i]);
                if (next[now][id] == -1)
                    next[now][id] = newnode();
                now = next[now][id];
            }
            disease[now] = true;
        }
    
        void build()
        {
            queue<int>Q;
            fail[root] = root;
            for (int i = 0; i < MAX_CHILD_NUM; i++)
                if (next[root][i] == -1)
                    next[root][i] = root;
                else
                {
                    fail[next[root][i]] = root;
                    Q.push(next[root][i]);
                }
            while (!Q.empty())
            {
                int now = Q.front();
                Q.pop();
                for (int i = 0; i < MAX_CHILD_NUM; i++)
                    if (next[now][i] == -1)
                        next[now][i] = next[fail[now]][i];
                    else
                    {
                        fail[next[now][i]]=next[fail[now]][i];
                        if (disease[fail[next[now][i]]])
                            disease[next[now][i]] = true;
                        Q.push(next[now][i]);
                    }
            }
        }
    
        int work()
        {
            scanf("%s", dna);
            int len = strlen(dna);
            for (int i = 0; i < node_cnt; i++)
            {
                if (disease[i])
                    dp[len][i] = INF;
                else
                    dp[len][i] = 0;
            }
            for (int i = len - 1; i >= 0; i--)
            {
                int key = get_id(dna[i]);
                for (int j = 0; j < node_cnt; j++)
                {
                    dp[i][j] = INF;
                    if (disease[j])
                        continue;
                    for (int k = 0; k < 4; k++)
                    {
                        int temp = 1;
                        if (k == key)
                            temp = 0;
                        int v = next[j][k];
                        if (disease[v])
                            continue;
                        dp[i][j] = min(dp[i][j], temp + dp[i + 1][v]);
                        D(printf("%d
    ", dp[i + 1][next[j][k]]));
                    }
                    D(printf("dp[%d][%d]=%d
    ", i, j, dp[i][j]));
                }
            }
            return dp[0][root];
        }
    
        void debug()
        {
            for(int i = 0;i < node_cnt;i++)
            {
                printf("id = %3d,fail = %3d,end = %3d,chi = [",i,fail[i],disease[i]);
                for(int j = 0;j < MAX_CHILD_NUM;j++)
                    printf("%2d",next[i][j]);
                printf("]
    ");
            }
        }
    }ac;
    
    int n;
    char st[MAX_D_LEN];
    
    int main()
    {
        int case_num = 1;
        while (scanf("%d", &n), n)
        {
            ac.init();
            for (int i = 0; i < n; i++)
            {
                scanf("%s", st);
                ac.insert(st);
            }
            ac.build();
            int ans = ac.work();
            if (ans >= INF)
                ans = -1;
            printf("Case %d: %d
    ", case_num++, ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    ADB——模拟手机按键输入
    ADB——连接手机的三种方式
    ADB——命令大全
    react-native 入门教程
    react-native-vector-icons 安装
    nginx静态资源缓存与压缩
    ReactNative开发工具有这一篇足矣
    Centos7源代码安装freeswitch和启动freeswitch
    windows 64位下,React-Native环境搭建详解 (Android)
    网站启用SSL后重启Nginx提示 Enter PEM Pass Phrase:需要输入密码
  • 原文地址:https://www.cnblogs.com/rainydays/p/4363868.html
Copyright © 2011-2022 走看看