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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

【Luogu3041】视频游戏的连击(AC自动机,动态规划)

發(fā)布時(shí)間:2023/11/27 生活经验 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Luogu3041】视频游戏的连击(AC自动机,动态规划) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題面鏈接

題解

首先構(gòu)建出AC自動(dòng)機(jī)
然后在AC自動(dòng)機(jī)上面跑DP
轉(zhuǎn)移很顯然從Trie樹的節(jié)點(diǎn)跳到他的兒子節(jié)點(diǎn)
但是要注意一個(gè)問題,
在計(jì)算的時(shí)候,每一個(gè)節(jié)點(diǎn)加入后能夠
造成的貢獻(xiàn)
要加上他的子串的貢獻(xiàn)
至于DP:
設(shè)f[i][j]表示已經(jīng)使用了i個(gè)字母
當(dāng)前在Trie樹的第j個(gè)節(jié)點(diǎn)上面能夠產(chǎn)生的最大貢獻(xiàn)
很顯然,轉(zhuǎn)移到他的兒子節(jié)點(diǎn)上面,同時(shí)統(tǒng)計(jì)貢獻(xiàn)即可

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>
using namespace std;
#define INF 1000000
int N,K;
int tot=0,ans;
char s[20];
int f[1100][400];
struct Node
{int vis[3];int p;int fail;
}t[5000];
void Add(char *s)
{int l=strlen(s);int now=0;for(int i=0;i<l;++i){if(!t[now].vis[s[i]-'A'])t[now].vis[s[i]-'A']=++tot;now=t[now].vis[s[i]-'A'];}t[now].p++;
}
void Build()
{queue<int> Q;for(int i=0;i<3;++i)if(t[0].vis[i])Q.push(t[0].vis[i]);while(!Q.empty()){int u=Q.front();Q.pop();for(int i=0;i<3;++i){if(t[u].vis[i]){t[t[u].vis[i]].fail=t[t[u].fail].vis[i];Q.push(t[u].vis[i]);}elset[u].vis[i]=t[t[u].fail].vis[i];}t[u].p+=t[t[u].fail].p;}
}
void DP()
{for(int T=0;T<=K;++T)for(int i=1;i<=tot;++i)f[T][i]=-INF;for(int T=1;T<=K;++T)for(int i=0;i<=tot;++i)for(int j=0;j<3;++j)f[T][t[i].vis[j]]=max(f[T][t[i].vis[j]],f[T-1][i]+t[t[i].vis[j]].p);for(int i=0;i<=tot;++i)ans=max(ans,f[K][i]);
}
int main()
{scanf("%d%d",&N,&K);for(int i=1;i<=N;++i){scanf("%s",s);Add(s);}Build();DP();printf("%d\n",ans);return 0;
}

轉(zhuǎn)載于:https://www.cnblogs.com/cjyyb/p/7647485.html

總結(jié)

以上是生活随笔為你收集整理的【Luogu3041】视频游戏的连击(AC自动机,动态规划)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。