洛谷 P3041 [USACO12JAN] Video Game Combos

Posted 蒟蒻JHY

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷 P3041 [USACO12JAN] Video Game Combos相关的知识,希望对你有一定的参考价值。

题目描述

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?

贝西在玩一款游戏,该游戏只有三个技能键 “A”“B”“C”可用,但这些键可用形成N种(1 <= N<= 20)特定的组合技。第i个组合技用一个长度为1到15的字符串S_i表示。

当贝西输入的一个字符序列和一个组合技匹配的时候,他将获得1分。特殊的,他输入的一个字符序列有可能同时和若干个组合技匹配,比如N=3时,3种组合技分别为"ABA", "CB", 和"ABACB",若贝西输入"ABACB",他将获得3分。

若贝西输入恰好K (1 <= K <= 1,000)个字符,他最多能获得多少分?

输入输出格式

输入格式:

 

  • 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.

 

输出格式:

 

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

 

输入输出样例

输入样例#1: 
3 7
ABA
CB
ABACB
输出样例#1: 
4


说明

The optimal sequence of buttons in this case is ABACBCB, which gives 4 points--1 from ABA, 1 from ABACB, and 2 from CB.


最简单的AC自动机+DP了。。。。再不会的话AC自动机白学了。

#include<bits/stdc++.h>
#define ll long long
#define maxn 1005
using namespace std;
int ch[maxn][3],n,m,k,ans=0;
int root=0,tot=0,val[maxn];
int f[maxn],g[maxn][maxn];
char s[maxn];

inline int id(char c){
    return c-A;
}

inline void ins(){
    int len=strlen(s),now=root;
    for(int i=0;i<len;i++){
        int c=id(s[i]);
        if(!ch[now][c]) ch[now][c]=++tot;
        now=ch[now][c];
    }
    val[now]=1;
}

inline void get_fail(){
    queue<int> q;
    for(int i=0;i<3;i++) if(ch[0][i]){
        q.push(ch[0][i]);
    }
    
    int r,v,x;
    while(!q.empty()){
        x=q.front(),q.pop();
        for(int i=0;i<3;i++){
            r=ch[x][i];
            if(!r){
                ch[x][i]=ch[f[x]][i];
                continue;
            }
            
            q.push(r);
            f[r]=ch[f[x]][i];
            val[r]+=val[f[r]];
        }
    }
}

inline void dp(){
    memset(g,-0x3f,sizeof(g));
    g[0][0]=0;
    int to;
    for(int i=0;i<k;i++)
        for(int j=0;j<=tot;j++)
            for(int u=0;u<3;u++){
                to=ch[j][u];
                g[i+1][to]=max(g[i+1][to],g[i][j]+val[to]);
            }
    
    for(int i=0;i<=tot;i++) ans=max(ans,g[k][i]);
}

int main(){
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++){
        scanf("%s",s);
        ins();
    }
    
    get_fail();
    dp();
    
    printf("%d\n",ans);
    return 0;
}

 

以上是关于洛谷 P3041 [USACO12JAN] Video Game Combos的主要内容,如果未能解决你的问题,请参考以下文章

P3041 [USACO12JAN]视频游戏的连击Video Game Combos

洛谷P3043 [USACO12JAN]牛联盟Bovine Alliance

洛谷 P3040 [USACO12JAN]贝尔分享Bale Share

洛谷—— P1561 [USACO12JAN]爬山Mountain Climbing

洛谷 P1561 [USACO12JAN]爬山Mountain Climbing

洛谷P3116 [USACO15JAN]约会时间Meeting Time