• hdu 2296 aC自动机+dp(得到价值最大的字符串)


    Ring

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 3180    Accepted Submission(s): 1033


    Problem Description
    For the hope of a forever love, Steven is planning to send a ring to Jane with a romantic string engraved on. The string's length should not exceed N. The careful Steven knows Jane so deeply that he knows her favorite words, such as "love", "forever". Also, he knows the value of each word. The higher value a word has the more joy Jane will get when see it.
    The weight of a word is defined as its appeared times in the romantic string multiply by its value, while the weight of the romantic string is defined as the sum of all words' weight. You should output the string making its weight maximal. 

     
    Input
    The input consists of several test cases. The first line of input consists of an integer T, indicating the number of test cases. Each test case starts with a line consisting of two integers: N, M, indicating the string's length and the number of Jane's favorite words. Each of the following M lines consists of a favorite word Si. The last line of each test case consists of M integers, while the i-th number indicates the value of Si.
    Technical Specification

    1. T ≤ 15
    2. 0 < N ≤ 50, 0 < M ≤ 100.
    3. The length of each word is less than 11 and bigger than 0.
    4. 1 ≤ Hi ≤ 100. 
    5. All the words in the input are different.
    6. All the words just consist of 'a' - 'z'.
     
    Output
    For each test case, output the string to engrave on a single line.
    If there's more than one possible answer, first output the shortest one. If there are still multiple solutions, output the smallest in lexicographically order.

    The answer may be an empty string. 
     
    Sample Input
    2
    7 2
    love ever
    5 5
    5 1
    ab
    5
     
    Sample Output
    lovever
    abab
    /*
    hdu 2296 aC自动机+dp(得到价值最大的字符串)
    
    给你m个子串,每个子串有自己的价值,让你求出长度为小于等于n的价值最大的字符串.
    要求字符串的长度尽可能的小,长度相同时字典序最小即可
    
    在生成状态转换图之后用,dp的思想解决.
    用dp[i][j]记录长度为i时且状态为j时的最大值,与此同时用str[i][j][55]记录这个字符串
    当价值相同时,对字符串进行比较即可.
    
    hhh-2016-04-24 17:13:36
    */
    #include <iostream>
    #include <vector>
    #include <cstring>
    #include <string>
    #include <cstdio>
    #include <queue>
    #include <algorithm>
    #include <functional>
    #include <map>
    using namespace std;
    #define lson  (i<<1)
    #define rson  ((i<<1)|1)
    typedef unsigned long long ll;
    typedef unsigned int ul;
    const int mod = 20090717;
    const int INF = 0x3f3f3f3f;
    const int N = 12*105;
    int tot;
    int n,m;
    char tp[55];
    int dp[55][N];
    char ans[55][N][55];
    
    struct Matrix
    {
        int len;
        int ma[111][111];
        Matrix() {};
        Matrix(int L)
        {
            len = L;
        }
    };
    
    int Compare(char a[],char b[])
    {
        int len1 = strlen(a);
        int len2 = strlen(b);
        if(len1 != len2) return len1 > len2;
        return strcmp(a,b);
    }
    
    struct Tire
    {
        int nex[N][26],fail[N],ed[N];
        int root,L;
        int newnode()
        {
            for(int i = 0; i < 26; i++)
                nex[L][i] = -1;
            ed[L++] = -1;
            return L-1;
        }
    
        void ini()
        {
            L = 0,root = newnode();
            memset(ed,-1,sizeof(ed));
        }
    
        int cal(char ch)
        {
            if(ch == 'A')
                return 0;
            else if(ch == 'C')
                return 1;
            else if(ch == 'G')
                return 2;
            else if(ch == 'T')
                return 3;
        }
    
        void inser(char buf[],int val)
        {
            int len = strlen(buf);
            int now = root;
            for(int i = 0; i < len; i++)
            {
                int ta = buf[i] - 'a';
                if(nex[now][ta] == -1)
                    nex[now][ta] = newnode();
                now = nex[now][ta];
            }
            ed[now] = val;
        }
    
        void build()
        {
            queue<int >q;
            fail[root] = root;
            for(int i = 0; i < 26; i++)
                if(nex[root][i] == -1)
                    nex[root][i] = root;
                else
                {
                    fail[nex[root][i]] = root;
                    q.push(nex[root][i]);
                }
            while(!q.empty())
            {
                int now = q.front();
                q.pop();
    //            if(ed[fail[now]])
    //                ed[now] = ed[fail[now]];
                for(int i = 0; i < 26; i++)
                {
                    if(nex[now][i] == -1)
                        nex[now][i] = nex[fail[now]][i];
                    else
                    {
                        fail[nex[now][i]] = nex[fail[now]][i];
                        q.push(nex[now][i]);
                    }
                }
            }
        }
    
        Matrix to_mat()
        {
            Matrix mat(L);
            memset(mat.ma,0,sizeof(mat.ma));
            for(int i = 0; i < L; i++)
            {
                for(int j = 0; j < 4; j++)
                {
                    if(!ed[nex[i][j]])
                        mat.ma[i][nex[i][j]] ++;
                }
            }
            return mat;
        }
    
        void solve()
        {
            for(int j = 0; j <= n; j++)
            {
                for(int i = 0; i < N; i++)
                    dp[j][i] = -1;
            }
            dp[0][0] = 0;
            char tan[55] = {""};
            int tMax = 0;
            strcpy(ans[0][0],"");
            strcpy(tp,"");
            for(int i = 1; i <= n; i++)
                for(int j = 0; j < N; j++)
                {
                    if(dp[i-1][j] >= 0)
                    {
                        strcpy(tp,ans[i-1][j]);
                        int len = strlen(tp);
                        for(int k = 0; k < 26; k++)
                        {
                            int t= dp[i-1][j];
                            if(ed[nex[j][k]] > 0)
                                t += ed[nex[j][k]];
                            tp[len] = 'a'+k;
                            tp[len+1] = 0;
                            if(t > dp[i][nex[j][k]] || (t == dp[i][nex[j][k]] && Compare(ans[i][nex[j][k]],tp) > 0))
                            {
                                strcpy(ans[i][nex[j][k]],tp);
                                dp[i][nex[j][k]] = t;
    
                            }
                            if(t >tMax || (tMax == t && Compare(tan,tp) > 0))
                            {
                                tMax = t;
                                strcpy(tan,tp);
                            }
                        }
                    }
                }
           // printf("%d
    ",tMax);
            printf("%s
    ",tan);
        }
    };
    
    
    
    Tire ac;
    char buf[105][12];
    
    
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&m);
            ac.ini();
            for(int i = 0; i < m; i++)
            {
                scanf("%s",buf[i]);
            }
            int x;
            for(int i = 0; i < m; i++)
            {
                scanf("%d",&x);
                ac.inser(buf[i],x);
            }
            ac.build();
            ac.solve();
        }
        return 0;
    }
    

      

  • 相关阅读:
    浓缩版java8新特性
    restful的认识和用法
    常用业务返回对象类ResponseJson
    微信小程序使用websocket通讯的demo,含前后端代码,亲测可用
    完整且易读的最新版小程序登录态和检验注册过没的app.js写法
    完整且易读的微信小程序的注册页面(包含倒计时验证码、获取用户信息)
    BCD工具类(8421)
    IDEA下使用protobuf2(java)
    chrome 调试技巧
    encodeURI和encodeURIComponent的区别?
  • 原文地址:https://www.cnblogs.com/Przz/p/5449323.html
Copyright © 2020-2023  润新知