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\n",ans); }
原文地址:https://www.cnblogs.com/suika/p/9063186.html