• BZOJ_2580_[Usaco2012 Jan]Video Game_AC自动机+DP


    BZOJ_2580_[Usaco2012 Jan]Video Game_AC自动机+DP

    Description

    Bessie is playing a video game! In the game, the three letters 'A', 'B', and 'C' are the only valid buttons. Bessie may press the buttons in any order she likes; however, there are only N distinct combos possible (1 <= N <= 20). Combo i is represented as a string S_i which has a length between 1 and 15 and contains only the letters 'A', 'B', and 'C'. Whenever Bessie presses a combination of letters that matches with a combo, she gets one point for the combo. Combos may overlap with each other or even finish at the same time! For example if N = 3 and the three possible combos are "ABA", "CB", and "ABACB", and Bessie presses "ABACB", she will end with 3 points. Bessie may score points for a single combo more than once. Bessie of course wants to earn points as quickly as possible. If she presses exactly K buttons (1 <= K <= 1,000), what is the maximum number of points she can earn? 

    给出n个ABC串combo[1..n]和k,现要求生成一个长k的字符串S,问S与word[1..n]的最大匹配数

    Input

     Line 1: Two space-separated integers: N and K. * Lines 2..N+1: Line i+1 contains only the string S_i, representing combo i.

    Output

    Line 1: A single integer, the maximum number of points Bessie can obtain.

    Sample Input

    3 7 ABA CB ABACB

    Sample Output

    4

    先对那些combo串建立AC自动机。
    每个节点维护出fail树的子树和。
    设F[i][j]表示i个字符,现在在j号节点上的最大匹配数
    转移就F[i+1][ch[j][c]]=max(F[i+1][ch[j][c]],F[i][j]+siz[ch[j][c]])即可。
     
    代码:
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    #define N 1050
    #define M 660
    int ch[M][3],fail[M],cnt=1,siz[M],f[N][M],n,m,Q[M],l,r;
    char w[22];
    void insert() {
        int i,p=1,lw=strlen(w+1);
        for(i=1;i<=lw;i++) {
            int &k=ch[p][w[i]-'A'];
            if(!k) k=++cnt; p=k;
        }
        siz[p]=1;
    }
    void build() {
        int p,i;
        for(i=0;i<3;i++) ch[0][i]=1;
        Q[r++]=1;
        while(l<r) {
            p=Q[l++];
            for(i=0;i<3;i++) {
                if(ch[p][i]) fail[ch[p][i]]=ch[fail[p]][i],Q[r++]=ch[p][i];
                else ch[p][i]=ch[fail[p]][i];
            }
            siz[p]+=siz[fail[p]];
        }
    }
    int main() {
        scanf("%d%d",&m,&n);
        int i,j,k;
        for(i=1;i<=m;i++) {
            scanf("%s",w+1);
            insert();
        }
        build();
        memset(f,0x80,sizeof(f));
        f[0][1]=0;
        for(i=1;i<=n;i++) {
            for(j=1;j<=cnt;j++) {
                for(k=0;k<3;k++) {
                    f[i][ch[j][k]]=max(f[i][ch[j][k]],f[i-1][j]+siz[ch[j][k]]);
                }
            }
        }
        int ans=0;
        for(i=1;i<=cnt;i++) ans=max(ans,f[n][i]);
        printf("%d
    ",ans);
    }
    

     

  • 相关阅读:
    pcb过孔盖油
    stm32的串口中断
    串口速度计算
    块元素、行内元素、行内块元素及其相互转化
    CSS伪类选择器
    CSS后代选择器、子代选择器
    CSS表示颜色、行间距、缩进、文字修饰
    CSS学习之通配符选择器
    【DP专题】——洛谷P0170道路游戏
    ssh框架jar包下载地址
  • 原文地址:https://www.cnblogs.com/suika/p/9063186.html
Copyright © 2020-2023  润新知