zoukankan      html  css  js  c++  java
  • 2020 CCPC Wannafly Winter Camp Day2 K题 破忒头的匿名信(AC自动机+dp)

    这题要看出dp更新的方法,因为我们有很多字符串,而最后的串可以随意组装而来

    因此dp状态设计为f[i]到i的最小代价,这也一直往下跳,更新的时候更新fail链上的所有答案,因为这些是可以成为他的后缀更新过来的,这也就枚举到了所有的情况

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=5e5+10;
    struct node{
        int cnt;
        node * nxt[27];
        node * fail;
        vector<node *> num;
    }*rt;
    node pool[N];
    int n,m,idx;
    ll val[N];
    int num;
    int st[N];
    ll f[N];
    void insert(string s,int x){
        node *p=rt;
        int i;
        for(i=0;i<s.size();i++){
            int sign=s[i]-'a';
            if(p->nxt[sign]==NULL){
                p->nxt[sign]=pool+(++idx);
                p->nxt[sign]->cnt=++num;
            }
            p=p->nxt[sign];
            if(i==(int)s.size()-1){
                if(!val[p->cnt])
                    val[p->cnt]=x;
                else
                val[p->cnt]=min(val[p->cnt],1ll*x);
                st[p->cnt]=(int)s.size();
            }
        }
    }
    void build(){
        int i;
        queue<node *> q;
        rt->fail=rt;
        for(i=0;i<26;i++){
            if(rt->nxt[i]){
                rt->nxt[i]->fail=rt;
                rt->num.push_back(rt->nxt[i]);
                q.push(rt->nxt[i]);
            }
            else{
                rt->nxt[i]=rt;
                rt->nxt[i]->fail=rt;
            }
        }
        while(q.size()){
            auto t=q.front();
            q.pop();
            for(i=0;i<26;i++){
                if(t->nxt[i]){
                    t->nxt[i]->fail=t->fail->nxt[i];
                    t->fail->nxt[i]->num.push_back(t->nxt[i]);
                    q.push(t->nxt[i]);
                }
                else{
                    t->nxt[i]=t->fail->nxt[i];
                }
            }
        }
    }
    void dfs(string s){
        int len=(int)s.size();
        int i,j;
        node *p=rt;
        for(i=0;i<len;i++){
            p=p->nxt[s[i]-'a'];
            node *x=p;
            while(x!=rt){
                if(st[x->cnt]){
                    f[i+1]=min(f[i+1],f[i+1-st[x->cnt]]+val[x->cnt]);
                }
                x=x->fail;
            }
        }
        if(f[len]==1e18){
            cout<<-1<<endl;
        }
        else{
            cout<<f[len]<<endl;
        }
    }
    int main(){
        ios::sync_with_stdio(false);
        rt=pool;
        rt->cnt=0;
        int i,j;
        cin>>n;
        for(i=1;i<=n;i++){
            string s;
            int x;
            cin>>s>>x;
            insert(s,x);
        }
        build();
        string s;
        cin>>s;
        for(int i=0;i<=(int)s.size();i++)
            f[i]=1e18;
        f[0]=0;
        dfs(s);
    }
    View Code
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    输入url后的加载过程~
    编写一个方法,求字符串长度~~~
    闭包 什么是闭包 为什么用闭包~~
    作用域链的理解~~
    谈谈javascript的基本规范~~~~
    html中datalist 是什么??????
    elementui中el-input联想搜索框
    js中数组对象去重的方法
    vue视频截图第一帧demo
    styled-components的基本使用
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/14123344.html
Copyright © 2011-2022 走看看