HDU 2296 AC自动机+DP

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yqdjl6/article/details/83030208

这道题就是普通的求单词贡献最大,然后让你输出这个单词是多少,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;
}

猜你喜欢

转载自blog.csdn.net/yqdjl6/article/details/83030208