[Luogu3041][USACO12JAN]视频游戏的连击Video Game Combos
生活随笔
收集整理的这篇文章主要介绍了
[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\n",ans);return 0; }转载于:https://www.cnblogs.com/zhoushuyu/p/8350050.html
总结
以上是生活随笔为你收集整理的[Luogu3041][USACO12JAN]视频游戏的连击Video Game Combos的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: TPS61088RHLR升压芯片
- 下一篇: Specify @BootstrapWi