HDU 4117 GRE Words

题目意思   就是给你  N 个单词,然后按照  顺序 后面一个单词是前面一个单词的字串,则可以记忆;每个单词有自己的价值;要求最大价值;

方法        这题  没有 刷掉;要用到  线段数等数据结构来优化;模仿了一个超时的版本;  也就是先建树,然后一个一个字符的插入,上面 那 spoj 上的dp 方法类似;就是,如果这个字符能成为一个单词的字串;则用记录最优值;在最底层的时候把价值全部加上去;明显是超时的, 因为对每个节点来说,都要找他的所有最长前缀,不然就会wa 因为单词可以重复,可能在后面的单词里面会价值会发生改变,变大了,不能保存最优值;

超时了   谁能教我  优化

#include<iostream>
#include<stdio.h>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;

struct date
{
    date *next[26],*fail;
    int sum,cnt;
    bool falg;
}tree[1123456],*que[1123456],*root;

int    res[21234],tail,head,ptr,N;
string str[21234];

date *creat_node( )
{
    for( int i = 0; i < 26; i++ )
       tree[ptr].next[i] = NULL;
    tree[ptr].fail = NULL;
    tree[ptr].sum  = 0;
    return &tree[ptr++];
}

void inint( )
{
    tail = head = ptr = 0;
    root = creat_node( );
}

void insert( int i,int val )
{
    date *temp = root;
    for( int j = 0; j < str[i].length(); j++ )
    {
        int num = str[i][j] - 'a';
        if( temp->next[num] == NULL )
            temp->next[num] = creat_node();
        temp = temp->next[num];
    }
}

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];
            que[tail++] = temp->next[i];
        }
        else
        {
            if( temp == root ) temp->next[i] = root;
            else               temp->next[i] = temp->fail->next[i];
        }
    }
}

void query( int i,int val )
{
    date *patten,*temp = root;
    int Max = 0;
    for( int j = 0; j < str[i].length(); j++ )
    {
        int num = str[i][j] -'a';
        temp = temp->next[num];
        Max = max( Max,temp->sum );
        patten = temp;
        while( patten != root )
        {
            Max = max( Max,patten->sum );
            patten = patten->fail;
        }
    }
    temp->sum = Max + val;
    res[i] = Max + val;
}

int main( )
{
    int val[21234],k = 1,T;
    scanf("%d",&T);
    while( T-- )
    {
        scanf("%d",&N);
        inint( );
        memset( res,0,sizeof(res) );
        for( int i = 1; i <= N; i++ )
        {
            cin>>str[i]>>val[i];
            if( val > 0 ) insert( i,val[i] );
        }
        build_AC( );
        for( int i = 1; i <= N ;i++ )
        if( val[i] > 0 )
            query( i,val[i] );
        int ans = 0;
        for( int i = 1; i <= N; i++ )
        ans = max( ans,res[i] );
        printf( "Case #%d: %d\n",k++,ans);
    }
    return 0;
}

/*

7 7
aaaa 12
aa 25
aaa 12
aaaaa 1
aaaaa 5
aaa 13
a 11

1
5
a 1
ab 2
abb 3
baba 5
abbab 8

*/
原文地址:https://www.cnblogs.com/wulangzhou/p/3016681.html