HDU 2296 AC自動機+DP
阿新 • • 發佈:2018-11-14
這道題就是普通的求單詞貢獻最大,然後讓你輸出這個單詞是多少,wa了老半天,最後調了好久,比較字串先比較長度,長度短的優先,然後再比較字典序
#include<bits/stdc++.h> using namespace std; using LL = int64_t; const int maxnode=1e6+5; const int sigma_size=27; char s[maxnode]; struct Node { int son[sigma_size]; int val,fail; }ch[maxnode]; struct NODE{ char s[105]; int num; }node[105]; int dp[55][1005],n,m; string path[55][1005]; bool check(string x,string y) { if(x.length()>y.length()) return true; if(x.length()==y.length()&&x>y) return true; return false; } struct AC { int sz=1; queue<int>Q; void init(int x) {ch[x].fail=ch[x].val=0;memset(ch[x].son,0,sizeof(ch[x].son));} int idx(char c) {return c-'a';} void insert(char s[],int v) { int u=0,n=strlen(s); for(int i=0;i<n;i++) { int c=idx(s[i]); if(!ch[u].son[c]) { init(sz); ch[u].son[c]=sz++; } u=ch[u].son[c]; } ch[u].val=v; } void build() { for(int i=0;i<26;i++) if(ch[0].son[i]) Q.push(ch[0].son[i]); while(!Q.empty()) { int now=Q.front();Q.pop(); int fail=ch[now].fail; for(int i=0;i<26;i++) { int nxt=ch[now].son[i]; if(nxt) { ch[nxt].fail=ch[fail].son[i]; Q.push(nxt); } else ch[now].son[i]=ch[fail].son[i]; //if(ch[ch[now].son[i]].val)ch[ch[now].son[i]].val+=ch[ch[ch[now].fail].son[i]].val; } } } void solve() { //for(int i=0;i<sz;i++) cout<<ch[i].val<<endl; for(int i=0;i<=n;i++) { for(int j=0;j<sz;j++) { dp[i][j]=-1;path[i][j].clear(); } } dp[0][0]=0; for(int i=0;i<=n;i++) { for(int j=0;j<sz;j++) { for(int k=0;k<26;k++) { if(dp[i][j]==-1) continue; if(dp[i][j]+ch[ch[j].son[k]].val>dp[i+1][ch[j].son[k]]) { dp[i+1][ch[j].son[k]]=dp[i][j]+ch[ch[j].son[k]].val; path[i+1][ch[j].son[k]]=path[i][j]+(char)(k+'a'); //cout<<path[i+1][ch[j].son[k]]<<" "<<dp[i+1][ch[j].son[k]]<<endl; } else if(dp[i][j]+ch[ch[j].son[k]].val==dp[i+1][ch[j].son[k]]&&check(path[i+1][ch[j].son[k]],path[i][j]+(char)(k+'a'))) { dp[i+1][ch[j].son[k]]=dp[i][j]+ch[ch[j].son[k]].val; path[i+1][ch[j].son[k]]=path[i][j]+(char)(k+'a'); //cout<<path[i+1][ch[j].son[k]]<<" "<<dp[i+1][ch[j].son[k]]<<endl; } } } } int x=0,y=0,maxs=0; for(int i=0;i<=n;i++) { for(int j=0;j<sz;j++) { if(dp[i][j]>dp[x][y]) x=i,y=j; else if(dp[i][j]==dp[x][y]&&check(path[x][y],path[i][j])) x=i,y=j; //cout<<path[i][j]<<"\n"; } //cout<<endl; } if(dp[x][y]<=0) cout<<"\n"; else cout<<path[x][y]<<"\n"; } }ans; int main() { ios::sync_with_stdio(0); cin.tie(0);cout.tie(0); int T;cin>>T; while(T--) { ans.init(0);ans.sz=1; cin>>n>>m; for(int i=1;i<=m;i++)cin>>node[i].s; for(int i=1;i<=m;i++) { cin>>node[i].num; ans.insert(node[i].s,node[i].num); } ans.build();ans.solve(); } return 0; }