【题解】[USACO12JAN]视频游戏的连击Video Game Combos
生活随笔
收集整理的這篇文章主要介紹了
【题解】[USACO12JAN]视频游戏的连击Video Game Combos
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
好久沒有寫博客了,好慚愧啊……雖然這是一道弱題但還是寫一下吧。
這道題目的思路應該說是很容易形成:字符串+最大值?自然聯想到學過的AC自動機與DP。對于給定的字符串建立出AC自動機,dp狀態dp[i][j]則表示第i位(我們求的字符串的第i位),匹配到自動機的第j位所能獲得的最大值。只需要沿兒子節點與fail指針轉移即可。
#include <bits/stdc++.h> using namespace std; #define maxn 1005 int n, m, ans, cnt; int dp[maxn][maxn], ch[maxn][4], tag[maxn * 4], fail[maxn * 4]; string s;void Gmax(int &x, int y) {if(y > x) x = y; }void Trie_Ins() {int len = s.length(), now = 0; for(int i = 0; i < len; i ++){if(!ch[now][s[i] - 'A']) ch[now][s[i] - 'A'] = ++ cnt;now = ch[now][s[i] - 'A'];} tag[now] += 1; }void AC_Build() {queue <int> q; for(int i = 0; i < 3; i ++) if(ch[0][i]) q.push(ch[0][i]);while(!q.empty()){int u = q.front(); q.pop();for(int i = 0; i < 3; i ++){if(ch[u][i]) {fail[ch[u][i]] = ch[fail[u]][i];tag[ch[u][i]] += tag[fail[ch[u][i]]];//注意不是加1哦q.push(ch[u][i]);}else ch[u][i] = ch[fail[u]][i];}} }void DP() {dp[0][0] = 0;for(int i = 1; i <= m; i ++)for(int j = 0; j <= cnt; j ++){if(dp[i - 1][j] == -1) continue;for(int k = 0; k < 3; k ++){if(ch[j][k]) Gmax(dp[i][ch[j][k]], dp[i - 1][j] + tag[ch[j][k]]);else Gmax(dp[i][fail[ch[j][k]]], dp[i - 1][j] + tag[fail[ch[j][k]]]);}} }int main() {scanf("%d%d", &n, &m);memset(dp, -1, sizeof(dp));for(int i = 1; i <= n; i ++){cin >> s;Trie_Ins();}AC_Build();DP();for(int i = 0; i <= cnt; i ++) ans = max(ans, dp[m][i]);printf("%d\n", ans);return 0; }?
轉載于:https://www.cnblogs.com/twilight-sx/p/8706503.html
總結
以上是生活随笔為你收集整理的【题解】[USACO12JAN]视频游戏的连击Video Game Combos的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 项目二 课后习题
- 下一篇: 5行Python代码就能让你的电脑 “永