NEFU 1267 挑战字符串 (AC自动机+贪心)好题

来源:互联网 发布:软装搭配软件 编辑:程序博客网 时间:2024/05/29 08:33

题意:

中文

思路:

建立 AC自动机 时记录下每个子串的长度dep

对母串进行匹配时

ans[i] 代表匹配到母串位置 i 的最大的答案

状态转移为:

ans[i]=max(ans[i],ans[i-dep[rt]]+val[rt])

代码:

ans[i]=max(ans[i],ans[i-dep[rt]]+val[rt]);#include <iostream>#include <queue>#include <cstdio>#include <algorithm>#include <cmath>#include <cstring>using namespace std;const int MAXN=1e3+7;int n,cnt;int ans[MAXN*MAXN];int son[MAXN*MAXN][27];int fail[MAXN*MAXN];int val[MAXN*MAXN];int dep[MAXN*MAXN];void newnode(){    cnt++;    for(int i=0;i<26;i++) son[cnt][i]=0;    val[cnt]=0;}void ini(){    cnt=0;    dep[1]=0;    newnode();    fail[1]=0;}void insert(){    string str;    int v;    cin>>str>>v;    int rt=1;    int len=str.size();    for(int i=0;i<len;i++){        int ch=str[i]-'a';        if(!son[rt][ch]) newnode(),son[rt][ch]=cnt,dep[cnt]=dep[rt]+1;        rt=son[rt][ch];    }    val[rt]=v;}void get_fail(){    queue <int> que;    que.push(1);    while(!que.empty()){        int now=que.front();        que.pop();        for(int i=0;i<26;i++){            if(son[now][i]){                int pos=fail[now];                while(pos){                    if(son[pos][i]){                        fail[son[now][i]]=son[pos][i];                        break;                    }                    pos=fail[pos];                }                if(!pos) fail[son[now][i]]=1;                que.push(son[now][i]);            }        }    }}int query(){    string str;cin>>str;    int len=str.size();    int rt=1;    for(int i=0;i<len;i++){        ans[i]=0;        if(i>0) ans[i]=ans[i-1];        int ch=str[i]-'a';        while(1){            if(rt==0){                rt=1;                break;            }            if(son[rt][ch]){                rt=son[rt][ch];                if(val[rt]){                    ans[i]=max(ans[i],ans[i-dep[rt]]+val[rt]);                }                break;            }            rt=fail[rt];        }    }    return *max_element(ans,ans+len);}int main(){    ios::sync_with_stdio(false);    //freopen("data.in","r",stdin);    //freopen("out.txt","w",stdout);    while(cin>>n){        ini();        for(int i=0;i<n;i++) insert();        get_fail();        cout<<query()<<endl;    }}


原创粉丝点击