zoukankan      html  css  js  c++  java
  • Ring

    题目大意:斯蒂文想送给他女盆友一个戒指,并且他想在戒指上刻一些字,他非常了解他女盆友喜欢什么单词,比如"love""forvevr"....并且他还把女盆友喜欢的单词弄了一个高兴度,他现在准备在这个戒指上刻上一个长度不超过N的句子,并且这个句子的高兴度是最大的,如果有多个这样的句子,选择最短的,如果还有多个选择字典序最小的。
     
    分析:比较容易想到DP来做,定义数组dp[Ni][kNode],保存第i长度到达k节点的最大价值,然后再用一个数组来保存路径就行了,注意dp数组初始化的时候应该初始化成一个很小的值...在这wa了好多次......................
     
    代码如下:
    ======================================================================================================================================
    #include<iostream>
    #include<algorithm>
    #include<stdio.h>
    #include<string.h>
    #include<queue>
    using namespace std;
    
    const int MAXN = 1207;
    const int MAXM = 57;
    const int MaxSon = 26;
    const int oo = 1e9+7;
    
    int dp[MAXM][MAXN];
    char path[MAXM][MAXN][MAXM];
    
    struct Ac_Trie
    {
        int next[MAXN][MaxSon];
        int Fail[MAXN], End[MAXN];
        int cnt, root;
    
        int newnode()
        {
            for(int i=0; i<MaxSon; i++)
                next[cnt][i] = -1;
            Fail[cnt] = End[cnt] = false;
    
            return cnt++;
        }
        void InIt()
        {
            cnt = 0;
            root = newnode();
        }
    
        void Insert(char s[], int val)
        {
            int now = root;
    
            for(int i=0; s[i]; i++)
            {
                int k = s[i]-'a';
    
                if(next[now][k] == -1)
                    next[now][k] = newnode();
                now = next[now][k];
            }
    
            End[now] = val;
        }
        void GetFial()
        {
            queue<int>Q;
            int now = root;
    
            for(int i=0; i<MaxSon; i++)
            {
                if(next[now][i] == -1)
                    next[now][i] = root;
                else
                {
                    Fail[next[now][i]] = root;
                    Q.push(next[now][i]);
                }
            }
    
            while(Q.size())
            {
                now = Q.front();
                Q.pop();
    
                for(int i=0; i<MaxSon; i++)
                {
                    if(next[now][i] == -1)
                        next[now][i] = next[Fail[now]][i];
                    else
                    {
                        Fail[next[now][i]] = next[Fail[now]][i];
                        Q.push(next[now][i]);
                    }
                }
            }
        }
    };
    Ac_Trie ac;
    
    bool cmp(char a[], char b[])
    {
        int len_a = strlen(a);
        int len_b = strlen(b);
    
        if(len_a != len_b)
            return len_a > len_b;
        return strcmp(a, b) > 0;
    }
    
    int main()
    {
        int T;
    
        scanf("%d", &T);
    
        while(T--)
        {
            int i, j, k, N, M, val;
            char s[107][17];
            ac.InIt();
    
            scanf("%d%d", &N, &M);
    
            for(i=0; i<M; i++)
                scanf("%s", s[i]);
    
            for(i=0; i<M; i++)
            {
                scanf("%d", &val);
                ac.Insert(s[i], val);
            }
    
            ac.GetFial();
    
            for(i=0; i<=N; i++)
            for(j=0; j<ac.cnt; j++)
                dp[i][j] = -oo;
    
            memset(path, false, sizeof(path));
    
            char ans[MAXM] = {0};
            int Max = 0;
            dp[0][0] = 0;
    
            for(i=0; i<N; i++)
            for(j=0; j<ac.cnt; j++)
            {
                char temp[57] = {0};
                strcpy(temp, path[i][j]);
                int len = strlen(temp);
    
                for(k=0; k<MaxSon; k++)
                {
                    int next = ac.next[j][k];
                    temp[len] = k+'a';
    
                    val = dp[i][j]+ac.End[next];
    
                    if(dp[i+1][next] < val || (dp[i+1][next]==val && cmp(path[i+1][next], temp) ) )
                    {
                        dp[i+1][next] = val;
                        strcpy(path[i+1][next], temp);
    
                        if(Max < val || (Max==val && cmp(ans, temp)))
                        {
                            Max = val;
                            strcpy(ans, temp);
                        }
                    }
                }
            }
            printf("%s
    ", ans);
        }
    
        return 0;
    }
  • 相关阅读:
    【模板】线段树
    【模板】快速幂
    【模板】SPFA
    【模板】链式前向星
    C语言博客作业--函数嵌套调用
    C语言博客作业--结构体
    C博客作业--指针
    C语言博客作业--字符数组
    C语言博客作业--一二维数组
    C语言博客作业--函数
  • 原文地址:https://www.cnblogs.com/liuxin13/p/4759677.html
Copyright © 2011-2022 走看看