HDU 2296
很明显的DP状态了,设dp[i][j],设当前在状态点i,经过j步能得到的最大分值。也是从root直接扩展就可以了。
至于字符串,实在有点困难,开始想着记录路径,但后来发现路径从后往前回溯不一定是字典序最小,夭折。。。看别人的,发现直接就把字符串存下来,跪了,也对,毕竟才50个。
直接存字符串,比较,选最小,即可。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <climits>
#include <string.h>
#include <queue>
#include <cmath>
#include <map>
#include <vector>
#define LL __int64
using namespace std; const int Maxn=1110;
const int dictsize=26;
const int root=0;
const int inf=(1<<30);
int fail[Maxn],trie[Maxn][dictsize];
int hv[Maxn];
int tag[Maxn];
int head,tail,tot;
int que[Maxn];
char str[Maxn];
int n,m,anshv;
int dp[Maxn][55];
char dpc[Maxn][55][55];
char ans[55]; void Insert_trie(int s){
int p=0,i=0,index;
while(str[i]){
index=str[i]-'a';
if(trie[p][index]==-1) trie[p][index]=++tot;
p=trie[p][index];
i++;
}
tag[p]=s;
} void build_ac(){
head=tail=0;
que[tail++]=root;
while(head!=tail){
int tmp=que[head++];
int p=-1;
for(int i=0;i<dictsize;i++){
if(trie[tmp][i]!=-1){
if(tmp==root) fail[trie[tmp][i]]=root;
else{
p=fail[tmp];
while(p!=-1){
if(trie[p][i]!=-1){
fail[trie[tmp][i]]=trie[p][i];
break;
}
p=fail[p];
}
if(p==-1) fail[trie[tmp][i]]=root;
}
if(tag[fail[trie[tmp][i]]]>=0) tag[trie[tmp][i]]=tag[fail[trie[tmp][i]]];
que[tail++]=trie[tmp][i];
}
else{ //trie[tmp][i]==-1
if(tmp==root) trie[tmp][i]=root;
else{
p=fail[tmp];
while(p!=-1){
if(trie[p][i]!=-1){
trie[tmp][i]=trie[p][i];
break;
}
p=fail[p];
}
if(p==-1) trie[tmp][i]=root;
}
}
}
}
} bool cmp(char s1[],char s2[])
{
int len1=strlen(s1);
int len2=strlen(s2);
if(len1 != len2)return len1 < len2;
else return strcmp(s1,s2) < 0;
} int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
head=tail=tot=0;
memset(fail,-1,sizeof(fail));
memset(trie,-1,sizeof(trie));
memset(tag,-1,sizeof(tag));
for(int i=0;i<m;i++){
scanf("%s",str);
Insert_trie(i);
}
for(int i=0;i<m;i++)
scanf("%d",&hv[i]);
build_ac();
// cout<<"YES"<<endl;
for(int i=0;i<=tot;i++){
for(int j=0;j<=n;j++){
strcpy(dpc[i][j],"");
dp[i][j]=-1;
}
}
dp[0][0]=0;
strcpy(ans,"");
anshv=0;
for(int j=0;j<n;j++){
for(int i=0;i<=tot;i++){
if(dp[i][j]>=0){
strcpy(str,dpc[i][j]);
int len=strlen(str);
for(int k=0;k<dictsize;k++){
int son=trie[i][k];
str[len]='a'+k;
str[len+1]='\0';
int tt=dp[i][j];
if(tag[son]>=0)
tt+=hv[tag[son]];
if(dp[son][j+1]<tt||(tt==dp[son][j+1]&&cmp(str,dpc[son][j+1]))){
dp[son][j+1]=tt;
strcpy(dpc[son][j+1],str);
}
if(dp[son][j+1]>anshv||dp[son][j+1]==anshv&&cmp(dpc[son][j+1],ans)){
anshv=dp[son][j+1];
strcpy(ans,dpc[son][j+1]);
}
}
}
}
}
puts(ans);
}
return 0;
}
HDU 2296的更多相关文章
- hdu 2296 aC自动机+dp(得到价值最大的字符串)
Ring Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- HDU 2296 Ring (AC自动机+DP)
Ring Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- HDU 2296 Ring ( Trie图 && DP && DP状态记录)
题意 : 给出 m 个单词,每一个单词有一个权重,如果一个字符串包含了这些单词,那么意味着这个字符串拥有了其权重,问你构成长度为 n 且权重最大的字符串是什么 ( 若有权重相同的,则输出最短且字典序最 ...
- HDU 2296 Ring -----------AC自动机,其实我想说的是怎么快速打印字典序最小的路径
大冥神的代码,以后能贴的机会估计就更少了....所以本着有就贴的好习惯,= =....直接贴 #include <bits/stdc++.h> using LL = long long ; ...
- Ring - HDU 2296(自动机+dp)
题目大意:斯蒂文想送给他女盆友一个戒指,并且他想在戒指上刻一些字,他非常了解他女盆友喜欢什么单词,比如"love""forvevr"....并且他还把女盆友喜欢 ...
- HDU 2296:Ring
Problem Description For the hope of a forever love, Steven is planning to send a ring to Jane with a ...
- HDU 2296 Ring [AC自动机 DP 打印方案]
Ring Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submissio ...
- Ring HDU - 2296 AC自动机+简单DP和恶心的方案输出
题意: 就是现在给出m个串,每个串都有一个权值,现在你要找到一个长度不超过n的字符串, 其中之前的m个串每出现一次就算一次那个字符串的权值, 求能找到的最大权值的字符串,如果存在多个解,输出最短的字典 ...
- 【原创】AC自动机小结
有了KMP和Trie的基础,就可以学习神奇的AC自动机了.AC自动机其实就是在Trie树上实现KMP,可以完成多模式串的匹配. AC自动机 其实 就是创建了一个状态的转移图,思想很 ...
随机推荐
- 使用Web Workers处理线程
使用HTML 4和JavaScript创建出来的Web程序中,因为所有的处理都是在单线程中 HTML 5的Web Workers API,HTML 5中,一个Worker实际上为一个后台运行的线程.
- php处理类
Thomas Boutell 以及众多的开发者创造了以GD图形库闻名的一个图形软件库,用于动态的图形计算. GD提供了对于诸如C, Perl, Python, PHP, OCaml等等诸多编程语言的支 ...
- 2019手机号码JS正则表达式
前端的正则表达式验证往往是最繁多最复杂的,所以整理了一些最近自己常用的正则表达式,希望能对大家有所帮助! /* 合法uri */ export function validateURL(textval ...
- Windows7下caffe-ssd-microsoft下编译
整个编译可谓漫长 编译了两天 网上教程也很多 但是也很杂 遇到各种错误 总归是编完了 1.下载Windows版本的Caffe-SSD源码 下载链接:https://github.com/conner9 ...
- DeltaFish 校园物资共享平台 第六次小组会议
DeltaFish 校园物资共享平台 第六次小组会议 记录人:娄雨禛 2018.6.3 任务进度(2018.5.28-2018.6.3) 前端 李鑫:商品详情界面设计.总体配色分析 刘鼎乾:卖家页面初 ...
- Windows 下MySQL zip 安装
主要步骤: 1.下载解压到安装的文件夹 2.配置环境路径 3.配置my.ini文件,设置程序路径和数据存储路径 4.以管理员身份启动Mysqld install(提示sevice安装成功) 5.启动M ...
- 【python】random
1.random 和其他语言一样,返回大于等于0.小于1的浮点数 2.uniform(a,b) 返回大于等于a.小于等于b的浮点数 3.randint(a,b) 这个很好理解,返回一个介于a和b之间的 ...
- vsftp服务器搭建
1.FTP的主动模式和被动模式的区别: 最大的区别是数据端口并不总是20, 主动模式和被动模式的优缺点: 主动FTP对FTP服务器的管理和安全很有利,但对客户端的管理不利.因为FTP服务器企图与客户端 ...
- Deutsch lernen (09)
1. die Rückmeldung, -en 反馈,回馈:(销假)报到 die Rückmeldung zur Arbeit 2. dringend a. 紧急的,急切的 Ich brauche d ...
- 【技术累积】【点】【编程】【13】XX式编程
(原)函数式编程 核心概念 函数式一等公民(输入输出啥的都可以是函数): 纯函数,固定输入带来固定输出: 阅读性良好,无并发问题,但效率偏低: 大历史背景 旨在描述问题如何计算: 有两位巨擘对问题的可 ...