• HDU 2296 DP + AC


    题目    给你  N 个有价值的串,然后要你 在一个 长度 为  50 的字符组成的所有字符串里面 找到一个价值最大的串,如果,,,,,,,,

    方法   反正就那样把!! 可以考虑一个字符走到有价值串的末尾接着往下走,到根节点,如果根节点也进不去,那就没有什么用了,如果根节点进去了,当然也就会沿着字符往下走;这样不会影响到结果了;所以,,这样答案是对的, 至于 保存字符什么的,真的蛋疼死了,,,,,,,

    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    #include<cstring>
    #define max(a,b) ((a)>(b)?(a):(b));
    using namespace std;
    
    struct date 
    {
        date *next[26],*fail;
        int wi,in;
    }tree[2500],*que[2500],*root;
    int N,M,tail,head,total,val[120];
    char path[55][1500][55],cha[120][12];
    
    date *creat_node()
    {
        for( int i = 0; i < 26; i++ )
        tree[total].next[i] = NULL;
        tree[total].fail    = NULL;
        tree[total].wi      = 0;
        tree[total].in      = total;
        return &tree[total++];
    }
    
    void inint( )
    {
        tail = head = total = 0;
        root = creat_node();
        root->fail = root;
    }
    
    void insert( char *word,int wi )
    {
        date *temp = root;
        while( *word )
        {
            int num = *word - 'a';
            if( temp->next[num] == NULL )
                temp->next[num] = creat_node();
            temp  = temp->next[num];
            word++;
        }
        temp->wi += wi;
    }
    
    void build_AC( )
    {
        que[tail++] = root;
        while( tail > head )
        {
            date *temp = que[head++];
            for( int i = 0; i < 26; i++ )
            if( temp->next[i] != NULL )
            {
                if( temp == root ) temp->next[i]->fail = root;
                else               temp->next[i]->fail = temp->fail->next[i];
                temp->next[i]->wi += temp->next[i]->fail->wi;
                que[tail++] = temp->next[i];
            }
            else 
            {
                if( temp == root ) temp->next[i] = root;
                else               temp->next[i] = temp->fail->next[i];
            }
        }
    }
    
    int dp[55][1500];
    
    void DP( )
    {
       int i,j,k;
       memset( dp,-1,sizeof(dp) );
       dp[0][0] = 0;
       for( i = 0; i < N; i++ )
       for( j = 0; j < total; j++ )
       if( dp[i][j] != -1 )
       {
          for( k = 0; k < 26; k++ )
          {
             date *temp = tree[j].next[k];
             int wi = temp->wi;
             int in = temp->in;
             int len = strlen( path[i][j] );
             path[i][j][len] = (char)('a' + k );
             path[i][j][len+1] = '\0';
             if( dp[i][j] + wi > dp[i+1][in] )
             {
                 dp[i+1][in] = dp[i][j] + wi;
                   strcpy( path[i+1][in],path[i][j] );
             }
             else if( dp[i][j] + wi == dp[i+1][in] )
                  if( strcmp( path[i+1][in],path[i][j] ) > 0 )
                         strcpy( path[i+1][in],path[i][j] );
             path[i][j][len] = '\0';
          }
       }
       int res = 0;
       for( i = 1; i <= N; i++ )
       for( j = 0; j < total; j++ )
           res = max( res,dp[i][j] );
       char str[55];str[0] = '!';
       for( i = 1; i <= N; i++ )
       for( j = 0; j < total; j++ )
       if( dp[i][j] == res && ( str[0] == '!' || strlen(path[i][j]) < strlen(str) || ( strlen(path[i][j]) == strlen(str) && strcmp(str,path[i][j]) > 0 ) ) )
                                                        strcpy( str,path[i][j] );
       if( res == 0 ) printf("\n");
       else           printf("%s\n",str);
    }
    
    int main( )
    {
        int T,i;
        scanf("%d",&T);
        while( T-- )
        {
            inint( );
            scanf("%d%d",&N,&M);
            for( i = 1; i <= M; i++ )
                scanf("%s",&cha[i]);
            for( i = 1; i <= M; i++ )
                scanf("%d",&val[i]);
            for( i = 1; i <= M; i++ )
                insert( cha[i],val[i] );
            build_AC( );
            DP( );
        }
        return 0;
    }
    

     

  • 相关阅读:
    SDOI2017遗忘的集合
    菜鸡的考场emacs配置
    SDOI2017苹果树
    SDOI2017硬币游戏
    都11点了为什么还没有人阿克离场
    TJOI2013数字根
    HNOI2018毒瘤
    闵可夫斯基和
    三维凸包学习小记
    灭绝树学习小记
  • 原文地址:https://www.cnblogs.com/wulangzhou/p/3016791.html
Copyright © 2020-2023  润新知