zoukankan      html  css  js  c++  java
  • hdu 2296 AC自动机+DP+路径字符串记录(较麻烦)

    题意:给出n个字符串,以及每个字符串的权值,求权值最大,字符串长度不超过m,最短且字典序最小的字符串。

    //#pragma comment(linker, "/STACK:102400000")
    #include<cstdlib>
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<list>
    #include<queue>
    #include<stack>
    #include<vector>
    #define tree int o,int l,int r
    #define lson o<<1,l,mid
    #define rson o<<1|1,mid+1,r
    #define lo o<<1
    #define ro o<<1|1
    #define pb push_back
    #define mp make_pair
    #define ULL unsigned long long
    #define LL long long
    #define inf 0x7fffffff
    #define eps 1e-7
    #define N 1009
    #define M 26
    using namespace std;
    int m,n,T,t,x,y,u;
    int ch[N][M],v[N],sz;
    int f[N],last[N];
    char str[109][15];
    int d[N][55],pre[N][55],len[N][55];
    void init()
    {
        sz=1;
        memset(ch[0],0,sizeof(ch[0]));
        memset(v,0,sizeof(v));
        memset(last,0,sizeof(last));
        memset(d,-1,sizeof(d));
        memset(len,0,sizeof(len));
    }
    int idx(char c)
    {
        return c-'a';
    }
    void insert(char str[],int val)
    {
        int u=0;
        for(int i=0; str[i]; i++)
        {
            int c=idx(str[i]);
            if(!ch[u][c])
            {
                memset(ch[sz],0,sizeof(ch[sz]));
                ch[u][c]=sz++;
            }
            u=ch[u][c];
        }
        v[u]+=val;
    }
    void getac()
    {
        f[0]=0;
        queue<int>q;
        for(int c=0; c<M; c++)
        {
            int u=ch[0][c];
            if(u)
            {
                f[u]=0;
                q.push(u);
                last[u]=v[u];/////////////
            }
        }
        while(!q.empty())
        {
            int r=q.front();
            q.pop();
            for(int c=0; c<M; c++)
            {
                int u=ch[r][c];
                if(!u)
                {
                    ch[r][c]=ch[f[r]][c];
                }
                else
                {
                    q.push(u);
                    int s=f[r];
                    f[u]=ch[s][c];
                    last[u]=v[u]+last[f[u]];//////
                }
            }
        }
    }
    int dp(int u,int sub)
    {
        if(sub==n)return 0;
        int &ans=d[u][sub];
        if(ans!=-1)return ans;
        ans=0;
        for(int i=0; i<M; i++)
        {
            int c=ch[u][i];
            if(last[c]+dp(c,sub+1)>ans)//先保证值最大
            {
                ans=max(ans,last[c]+dp(c,sub+1));
                pre[u][sub]=i;
                if(ans>0)
                    len[u][sub]=len[c][sub+1]+1;
            }
            else if (last[c]+dp(c,sub+1)==ans&&len[u][sub]>len[c][sub+1]+1)//再保证长度最短
            {
                pre[u][sub]=i;
                if(ans>0)
                    len[u][sub]=len[c][sub+1]+1;
            }
        }
        return ans;
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("ex.in","r",stdin);
    #endif
        int ncase=0;
        scanf("%d",&T);
        while(T--)
        {
            init();
            scanf("%d%d",&n,&m);
            for(int i=0; i<m; ++i)
                scanf("%s",str[i]);
            for(int i=0; i<m; ++i)
            {
                scanf("%d",&t);
                insert(str[i],t);
            }
            getac();
            dp(0,0);
            int u=0,i=0;
            while(d[u][i]>0)
            {
                printf("%c",pre[u][i]+'a');
                u=ch[u][pre[u][i]];
                i++;
            }
            puts("");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    java poi 从服务器下载模板写入数据再导出
    一个华为面试题
    ForEach 循环
    fmt标签格式化数字和时间
    Ichars制作数据统计图
    jQuery中的事件
    oracle学习第四天
    GET请求和POST请求
    Jsp的九个隐含对象
    Oracle学习【语句查询】
  • 原文地址:https://www.cnblogs.com/sbaof/p/3375750.html
Copyright © 2011-2022 走看看