BZOJ 2580 Video Game 发表于 2017-01-09 | 更新于 2018-06-18 LinkSolution在每个节点上记录f[i]f[i]f[i]表示长度为iii的串匹配到当前节点的最大匹配数,更新后继节点的值即可。 Tips初始值的设置要仔细考虑。 Code123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106//Code by Lucida#include<bits/stdc++.h>//#define get(x) scanf("%d",&x)//#define debug(x) std::cout<<#x<<'='<<x<<std::endltemplate <class T> inline bool chkmx(T &a,const T &b){return a<b?a=b,1:0;}template <class T> inline bool chkmn(T &a,const T &b){return a>b?a=b,1:0;}const int MAXN=1000+10,INF=0x1f1f1f1f;using std::fill_n;namespace AC{ const char SB='A',SE='C'; const int SIGMA=SE-SB+1; const int SIZE=20*20; struct Node { Node *son[SIGMA],*fail,*last; int cnt,f[MAXN]; Node *&next(char c){return son[c-SB];} Node() { memset(son,0,sizeof(son)); fail=last=0;cnt=0; fill_n(f,sizeof(f)/sizeof(f[0]),-INF); } }*root=new Node,*POOL=(Node*)malloc(SIZE*sizeof(Node)),*ME=POOL; Node *newNode(){return new(ME++) Node;} void Insert(char *s) { Node *cur=root; for(int i=1,L=strlen(s+1);i<=L;i++) { if(!cur->next(s[i])) cur->next(s[i])=newNode(); cur=cur->next(s[i]); } cur->cnt++; } Node *Q[SIZE];int he,ta; void Build() { he=1,ta=0; root->fail=root; for(char c=SB;c<=SE;++c) if(!root->next(c)) root->next(c)=root; else { root->next(c)->fail=root; Q[++ta]=root->next(c); } while(he<=ta) { Node *cur=Q[he++]; for(char c=SB;c<=SE;++c) { Node *&son=cur->next(c); if(!son) son=cur->fail->next(c); else { son->fail=cur->fail->next(c); son->last=son->fail->cnt?son->fail:son->fail->last; if(son->last) son->cnt+=son->last->cnt; Q[++ta]=son; } } } } int DP(int K) { int res=0; root->f[0]=0; for(int i=1;i<=K;i++) { Q[he=ta=1]=root; while(he<=ta) { Node *cur=Q[he++]; for(char c=SB;c<=SE;++c) { Node *&son=cur->next(c); if(son->f[i]==-INF) { Q[++ta]=son; son->f[i]++; } chkmx(son->f[i],cur->f[i-1]+son->cnt); if(i==K) chkmx(res,son->f[K]); } } }//f[k] f[i] return res; }}using namespace AC;int main(){ freopen("input","r",stdin); static char s[MAXN]; int n,K;get(n),get(K); for(int i=1;i<=n;i++) scanf("%s",s+1),Insert(s); Build(); printf("%d\n",DP(K)); return 0;}/* AC Record(Bugs) * * RE the -1 at 74 isn't sure to be covered. * * * * * * * * * */