日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

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

编程问答

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

發布時間:2023/12/29 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。