Luogu P3041 USACO12JAN Video Game G 题解 [ 紫 ] [ AC 自动机 ] [ 动态规划 ]

Video Games G:弱智紫题,30min 切了,dp 思路非常板。

多模式串一看肯定就是要建出 AC 自动机,然后在 fail 树里下传标记,预处理每个节点到达后的得分。

然后设计 \(dp_{i,j}\) 表示第 \(i\) 个字符,AC 自动机里匹配节点在 \(j\) 的最大答案,刷表法转移即可:

\[dp_{i+1,ch_{j,c}} \gets \max(dp_{i+1,ch_{j,c}},dp_{i,j}+con_{ch_{j,c}}) \]

时间复杂度 \(O(nk\left|S\right|)\)

代码

#include <bits/stdc++.h>
#define fi first
#define se second
#define lc (p<<1)
#define rc ((p<<1)|1)
#define eb(x) emplace_back(x)
#define pb(x) push_back(x)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
using pi=pair<int,int>;
int n,m;
int ch[305][5],idx=0,ne[305],tot[305],dp[1005][305],ans=0;
char s[20];
vector<int>g[305];
void insert(char *s)
{
    int p=0;
    for(int i=1;s[i];i++)
    {
        int c=s[i]-'A';
        if(ch[p][c]==0)ch[p][c]=++idx;
        p=ch[p][c];
    }
    tot[p]++;
}
void 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++)
        {
            int v=ch[u][i];
            if(v)ne[v]=ch[ne[u]][i],q.push(v);
            else ch[u][i]=ch[ne[u]][i];
        }
    }
}
void dfs1(int u)
{
    for(auto v:g[u])
    {
        tot[v]+=tot[u];
        dfs1(v);
    }
}
void init()
{
    for(int i=1;i<=idx;i++)g[ne[i]].push_back(i);
    dfs1(0);
}
int main()
{
    //freopen("sample.in","r",stdin);
    //freopen("sample.out","w",stdout);
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin>>s+1;
        insert(s);
    }
    build();
    init();
    memset(dp,-0x3f,sizeof(dp));
    dp[0][0]=0;
    for(int lv=0;lv<m;lv++)
    {
        for(int p=0;p<=idx;p++)
        {
            for(int i=0;i<3;i++)
            {
                int v=ch[p][i];
                dp[lv+1][v]=max(dp[lv+1][v],dp[lv][p]+tot[v]);
            }
        }
    }
    for(int i=0;i<=idx;i++)ans=max(ans,dp[m][i]);
    cout<<ans;
    return 0;
}
posted @ 2025-01-07 19:49  KS_Fszha  阅读(1)  评论(0编辑  收藏  举报