zoukankan      html  css  js  c++  java
  • 【题解】[USACO12JAN]视频游戏的连击Video Game Combos

    好久没有写博客了,好惭愧啊……虽然这是一道弱题但还是写一下吧。

    这道题目的思路应该说是很容易形成:字符串+最大值?自然联想到学过的AC自动机与DP。对于给定的字符串建立出AC自动机,dp状态dp[i][j]则表示第i位(我们求的字符串的第i位),匹配到自动机的第j位所能获得的最大值。只需要沿儿子节点与fail指针转移即可。

    #include <bits/stdc++.h>
    using namespace std;
    #define maxn 1005
    int n, m, ans, cnt;
    int dp[maxn][maxn], ch[maxn][4], tag[maxn * 4], fail[maxn * 4];
    string s;
    
    void Gmax(int &x, int y)
    {
        if(y > x) x = y;
    }
    
    void Trie_Ins()
    {
        int len = s.length(), now = 0; 
        for(int i = 0; i < len; i ++)
        {
            if(!ch[now][s[i] - 'A']) ch[now][s[i] - 'A'] = ++ cnt;
            now = ch[now][s[i] - 'A'];
        }    
        tag[now] += 1;
    }
    
    void AC_Build()
    {
        queue <int> q; 
        for(int i = 0; i < 3; i ++) 
            if(ch[0][i]) q.push(ch[0][i]);
        while(!q.empty())
        {
            int u = q.front(); q.pop();
            for(int i = 0; i < 3; i ++)
            {
                if(ch[u][i]) 
                {
                    fail[ch[u][i]] = ch[fail[u]][i];
                    tag[ch[u][i]] += tag[fail[ch[u][i]]];//注意不是加1哦
                    q.push(ch[u][i]);
                }
                else ch[u][i] = ch[fail[u]][i];
            }
        }
    }
    
    void DP()
    {
        dp[0][0] = 0;
        for(int i = 1; i <= m; i ++)
            for(int j = 0; j <= cnt; j ++)
            {
                if(dp[i - 1][j] == -1) continue;
                for(int k = 0; k < 3; k ++)
                {
                    if(ch[j][k]) Gmax(dp[i][ch[j][k]], dp[i - 1][j] + tag[ch[j][k]]);
                    else Gmax(dp[i][fail[ch[j][k]]], dp[i - 1][j] + tag[fail[ch[j][k]]]);
                }
            }
    }
    
    int main()
    {
        scanf("%d%d", &n, &m);
        memset(dp, -1, sizeof(dp));
        for(int i = 1; i <= n; i ++)
        {
            cin >> s;
            Trie_Ins();
        }
        AC_Build();
        DP();
        for(int i = 0; i <= cnt; i ++) ans = max(ans, dp[m][i]);
        printf("%d
    ", ans);
        return 0;
    }
  • 相关阅读:
    kubernetes获取Pod内容器信息
    etcd空间配额2G限制优化
    kubernetes集群之GC处理
    kubernetes之statefulset控制器介绍
    基于MySQL Binlog的Elasticsearch数据同步实践
    Nacos
    Python最佳工程实践,建立一个完美的工程项目
    图数据库的内部结构 (NEO4j)
    5个用/不用GraphQL的理由
    Neo4J 查找两节点之间的路径
  • 原文地址:https://www.cnblogs.com/twilight-sx/p/8706503.html
Copyright © 2011-2022 走看看