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

    题面

    sol

    (f_{i,j})表示填了前(i)个字母,在(AC)自动机上跑到了节点(j)的最大得分。因为匹配需要暴跳(fail)所以预先把(fail)指针上面的匹配数传下来,这样就只要计算当前节点的贡献就可以了。

    code

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    using namespace std;
    const int N = 1005;
    int n,k,tot,ch[3][N],fail[N],cnt[N],dp[N][N],ans;
    char s[N];
    queue<int>Q;
    void Insert()
    {
        scanf("%s",s);int l=strlen(s);
        int x=0;
        for (int i=0;i<l;i++)
        {
            if (!ch[s[i]-'A'][x]) ch[s[i]-'A'][x]=++tot;
            x=ch[s[i]-'A'][x];
        }
        cnt[x]++;
    }
    void Get_Fail()
    {
        for (int i=0;i<3;i++) if (ch[i][0]) Q.push(ch[i][0]);
        while (!Q.empty())
        {
            int u=Q.front();Q.pop();
            for (int i=0;i<3;i++)
                if (ch[i][u]) fail[ch[i][u]]=ch[i][fail[u]],Q.push(ch[i][u]);
                else ch[i][u]=ch[i][fail[u]];
            cnt[u]+=cnt[fail[u]];
        }
    }
    void DP()
    {
        memset(dp,-127,sizeof(dp));dp[0][0]=0;
        for (int i=1;i<=k;i++)
            for (int j=0;j<=tot;j++)
                for (int l=0;l<3;l++)
                    dp[i][ch[l][j]]=max(dp[i][ch[l][j]],dp[i-1][j]+cnt[ch[l][j]]);
    }
    int main()
    {
        scanf("%d %d",&n,&k);
        for (int i=1;i<=n;i++) Insert();
        Get_Fail();
        DP();
        ans=dp[k][0];
        for (int i=1;i<=tot;i++) ans=max(ans,dp[k][i]);
        printf("%d
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    第13次作业--邮箱的正则表达式
    第11次作业--字符串处理
    第10次作业
    找回感觉的 练习
    《java技术》第十次作业
    《java》技术 第九次作业
    《java技术》第八次作业
    《java技术》第七次作业
    java实验六作业
    第五次实验作业
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/8350050.html
Copyright © 2011-2022 走看看