[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