HDU 2296 Ring(AC自动机+DP)

HDU 2296 Ring(AC自动机+DP)

http://acm.hdu.edu.cn/showproblem.php?pid=2296

题意:

        给你M个单词构成一个词典,每个单词有一个权值(单词出现多次算多个权值),现在要你构造一个不超过长度N的字符串,使得该字符串权值最大。如果出现多个答案,输出最短的,如果依然有多解,输出字典序最小的。

分析:

        本题和之前几题类似。不过注意这题的AC自动机要用match, match[i]表示i节点的后缀单词权值总和.后缀单词指的是:所有可以做i节点表示的串的后缀的单词.

       令dp[i][j]=x表示当前在i点走过了长j的路所生产的最大权值为x. 再用string  path[i][j]来保存那个具有最大权值的最优字符串即可.不过要注意如果最后算的的最大权值是0,那么要输出空串.因为空串最短.

dp[i][j] = max(dp[k][j-1]+match[i]) 若dp[i][j]更新的时候,path[i][j]也要看看是否需要更新成:

if(path[i][j]!=””)path[i][j] =  better(path[i][j] , path[k][j-1]+”x”)x字符表示从k走到i的那条边的字符是x.

初值path=空串,dp[0][0]=0.

注意:做这题的时候出现了几个错误的地方.

首先对于dp[i][j]不可达的节点一定要置-1,不能置1

其次对于当dp[ch[k][j]][len + 1] 时直接替换原来的path,而不是求最优了.

还有HDU提交这题的时候我一直编辑错误,不知道错在哪里?后来不得不改掉一些函数了.后来经过无数次的测试,发现少些了#include .

AC代码:

#include
#include
#include
#include
#include
#include
#include
using namespace std;
int N,M;
const int maxnode=1000+100;
const int sigma_size=26;
inline string better(string a,string b)
{
    if(a=="")
        return b;
    if(a.size()!=b.size())
        return a.size() q;
        for(int i=0;i


你可能感兴趣的:(ACM--题解汇总,★★★,注意!,数据结构--AC自动机,practice,again)