欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

P3041 [USACO12JAN]视频游戏的连击Video Game Combos

发布时间:2023/12/29 编程问答 46 豆豆
生活随笔 收集整理的这篇文章主要介绍了 P3041 [USACO12JAN]视频游戏的连击Video Game Combos 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

题意:贝西在玩一款游戏,该游戏只有三个技能键 “A”“B”“C”可用,但这些键可用形成N种(1 <= N<= 20)特定的组合技。第i个组合技用一个长度为1到15的字符串S_i表示。
当贝西输入的一个字符序列和一个组合技匹配的时候,他将获得1分。特殊的,他输入的一个字符序列有可能同时和若干个组合技匹配,比如N=3时,3种组合技分别为"ABA", “CB”, 和"ABACB",若贝西输入"ABACB",他将获得3分。
若贝西输入恰好K (1 <= K <= 1,000)个字符,他最多能获得多少分?

题解:这道题和文本生成器(题目链接)类似,没有刷过的可以尝试一下,感觉这种dp都是套路。
我们用dp[i][j]表示已经匹配的长度为i,当前在j节点的最大得分,然后从父亲往儿子转移即可,要注意的是,如果字符串的子串如果也是能得分的,我们应该将得分加到u中,表示该节点的得分

#include<bits/stdc++.h> using namespace std; const int MAXNODE = 1e6+50; const int INF = 0x3f3f3f3f; struct Trie{int nxt[MAXNODE][3],fail[MAXNODE],cnt[MAXNODE];int dp[1050][1050];int sz;void Insert(char *s){int root=0,len=strlen(s);for(int i=0;i<len;i++){if(!nxt[root][s[i]-'A']) nxt[root][s[i]-'A'] = ++sz;root = nxt[root][s[i]-'A'];}cnt[root]++;}void Build(){queue<int> que;for(int i=0;i<3;i++)if(nxt[0][i])que.push(nxt[0][i]);while(!que.empty()){int u = que.front();que.pop();for(int i=0;i<3;i++){if(nxt[u][i]) que.push(nxt[u][i]),fail[nxt[u][i]] = nxt[fail[u]][i];else nxt[u][i] = nxt[fail[u]][i];}cnt[u] += cnt[fail[u]];//该点的贡献值应该加上其子串(后缀)的得分}}void Solve(int len){memset(dp,-INF,sizeof(dp));dp[0][0]=0;for(int i=1;i<=len;i++)for(int j=0;j<=sz;j++)for(int k=0;k<3;k++)dp[i][nxt[j][k]] = max(dp[i][nxt[j][k]],dp[i-1][j]+cnt[nxt[j][k]]);int res = 0;for(int i=0;i<=sz;i++)res = max(res,dp[len][i]);printf("%d\n",res);} }Automata; char str[20]; int main(){int n,k;scanf("%d%d",&n,&k);for(int i=0;i<n;i++) scanf("%s",str),Automata.Insert(str);Automata.Build();Automata.Solve(k);return 0; }

总结

以上是生活随笔为你收集整理的P3041 [USACO12JAN]视频游戏的连击Video Game Combos的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。