大冥神的代码,以后能贴的机会估计就更少了。。。。所以本着有就贴的好习惯,= =。。。。直接贴

#include <bits/stdc++.h>
using LL = long long ;
#define ALL(v) (v).begin(),(v).end()
#define showtime fprintf(stderr,"time = %.15f\n",clock() / (double)CLOCKS_PER_SEC) char str[100][11];
int n,m;
int weight[100]; const int N = 10 * 100 + 5;
int go[N][26],val[N],fail[N],tot; int get_node() {
memset(go[tot],-1,sizeof(go[tot]));
val[tot] = 0;
return tot ++;
} int dp[50 + 1][N],pre[50 + 1][N],pc[50 + 1][N];
std::vector<int> order[50 + 1]; void insert(char *s,int w) {
int u = 0;
for ( ; *s; ++ s) {
int c = *s - 'a';
if (go[u][c] == -1)
go[u][c] = get_node();
u = go[u][c];
}
val[u] += w;
} std::string work() {
tot = 0;
get_node();
for (int i = 0; i < m; ++ i) {
insert(str[i],weight[i]);
}
std::vector<int> vec{0};
fail[0] = -1;
for (int I = 0; I < (int)vec.size(); ++ I) {
int u = vec[I];
for (int c = 0; c < 26; ++ c) {
if (go[u][c] == -1) continue;
int v = go[u][c];
int f = fail[u];
while (f != -1 && go[f][c] == -1) f = fail[f];
fail[v] = f == -1 ? 0 : go[f][c];
vec.push_back(v);
}
}
for (int I = (int)vec.size() - 1; I >= 0; -- I) {
int u = vec[I];
for (int c = 0; c < 26; ++ c) {
int f = u;
while (f != -1 && go[f][c] == -1) f = fail[f];
go[u][c] = f == -1 ? -1 : go[f][c];
}
for (int f = fail[u]; f != -1; f = fail[f]) {
val[u] += val[f];
}
}
memset(dp,-1,sizeof(dp));
memset(pre,-1,sizeof(pre));
dp[0][0] = 0;
for (int i = 0; i <= n; ++ i) {
order[i].clear();
}
order[0].push_back(0);
for (int i = 0; i < n; ++ i) {
for (int u : order[i]) {
for (int c = 0; c < 26; ++ c) {
if (go[u][c] == -1) continue;
int v = go[u][c];
dp[i + 1][v] = std::max(dp[i + 1][v],dp[i][u] + val[v]);
}
}
for (int u : order[i]) {
for (int c = 0; c < 26; ++ c) {
if (go[u][c] == -1) continue;
int v = go[u][c];
if (dp[i + 1][v] == dp[i][u] + val[v] && pre[i + 1][v] == -1) {
pre[i + 1][v] = u;
pc[i + 1][v] = c;
order[i + 1].push_back(v);
}
}
}
} int ai = 0,au = 0;
for (int i = 0; i <= n; ++ i) {
for (int u : order[i]) {
if (dp[i][u] > dp[ai][au]) {
ai = i;
au = u;
}
}
}
std::string ret;
while (ai) {
ret.push_back(pc[ai][au] + 'a');
au = pre[ai][au];
-- ai;
}
std::reverse(ALL(ret));
return ret;
} int main() {
int cas;
scanf("%d",&cas);
while (cas--) {
scanf("%d%d",&n,&m);
for (int i = 0; i < m; ++ i) {
scanf("%s",str[i]);
}
for (int i = 0; i < m; ++ i) {
scanf("%d",weight + i);
}
printf("%s\n",work().c_str());
}
}

  

HDU 2296 Ring -----------AC自动机,其实我想说的是怎么快速打印字典序最小的路径的更多相关文章

  1. HDU 2296 Ring [AC自动机 DP 打印方案]

    Ring Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submissio ...

  2. HDU 2296 Ring (AC自动机+DP)

    Ring Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  3. 2017多校第6场 HDU 6096 String AC自动机

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6096 题意:给了一些模式串,然后再给出一些文本串的不想交的前后缀,问文本串在模式串的出现次数. 解法: ...

  4. HDU 2296 Ring ( Trie图 && DP && DP状态记录)

    题意 : 给出 m 个单词,每一个单词有一个权重,如果一个字符串包含了这些单词,那么意味着这个字符串拥有了其权重,问你构成长度为 n 且权重最大的字符串是什么 ( 若有权重相同的,则输出最短且字典序最 ...

  5. HDU 2222(AC自动机模板题)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2222 题目大意:多个模式串.问匹配串中含有多少个模式串.注意模式串有重复,所以要累计重复结果. 解题 ...

  6. HDU 2296:Ring

    Problem Description For the hope of a forever love, Steven is planning to send a ring to Jane with a ...

  7. HDU2296 Ring —— AC自动机 + DP

    题目链接:https://vjudge.net/problem/HDU-2296 Ring Time Limit: 2000/1000 MS (Java/Others)    Memory Limit ...

  8. Hdu 5384 Danganronpa (AC自动机模板)

    题目链接: Hdu 5384 Danganronpa 题目描述: 给出n个目标串Ai,m个模式串Bj,问每个目标串中m个模式串出现的次数总和为多少? 解题思路: 与Hdu 2222  Keywords ...

  9. HDU-2296 Ring(AC自动机+DP)

    题目大意:给出的m个字符串都有一个权值.用小写字母构造一个长度不超过n的字符串S,如果S包含子串s,则S获取s的权值.输出具有最大权值的最小字符串S. 题目分析:先建立AC自动机.定义状态dp(ste ...

随机推荐

  1. struts2基础学习--环境配置(*原创)

    1) -->下载开发包,网址:http://struts.apache.org/download.cgi 本文使用的是struts-2.5.2-all开发包 2) -->导入jar包,具体 ...

  2. c# float显示时保存一位小数

    UI显示时候,需求保留一位小数 //保留一位小数 参考: http://blog.sina.com.cn/s/blog_620531730100kfz6.html float ff = 1.01f; ...

  3. [bzoj1269][AHOI2006文本编辑器editor] (splay模版题 or pb_ds [rope]大法)

    Description 这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器.你能帮助他吗?为了明确任务目标,可可对“文本编辑器”做了一个抽象的定义:   文本:由0个或 ...

  4. [LeetCode] Remove Duplicates from Sorted List II 移除有序链表中的重复项之二

    Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numb ...

  5. java版简易socket客户端

    android项目需要使用到心跳, 于是编写了一个简易的socket客户端程序 主要功能是给服务端发送心跳包,保持在线状态 没有使用框架,这样避免了需要引入包,直接使用的阻塞Socket通信. 主要逻 ...

  6. 多条件分页查找(SQL拼接方法)

    def startTime=params.startTime+" 00:00:00"  def endTime=params.endTime + " 23:59:59&q ...

  7. Javascript自执行匿名函数(function() { })()的原理分析

    匿名函数指没有指定函数名或指针的函数,自执行匿名函数只是其中一种,下文中称这种函数为:自执行函数 下面是一个最常见的自执行函数: // 传统匿名函数 (function() { alert('hell ...

  8. javascrip for 循环数组事件绑定

    //radio选择填充,字段 var radioArray = ["F_RegisterCode", "F_Subjection", "F_Mecha ...

  9. Nginx编译安装(Centos)

    前言 Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行.由俄罗斯的程序设计师Igor Sysoev所开发,供俄国大 ...

  10. win7搭建双系统ubuntu

    参考链接:http://www.linuxidc.com/Linux/2014-10/108430.htm 0.下载EasyBCD软件和ubuntu镜像1.在win7,右键我的电脑,磁盘管理,压缩卷, ...