vjudge

Description

For the hope of a forever love, Steven is planning to send a ring to Jane with a romantic string engraved on. The string's length should not exceed N. The careful Steven knows Jane so deeply that he knows her favorite words, such as "love", "forever". Also, he knows the value of each word. The higher value a word has the more joy Jane will get when see it.

The weight of a word is defined as its appeared times in the romantic string multiply by its value, while the weight of the romantic string is defined as the sum of all words' weight. You should output the string making its weight maximal.

Input

The input consists of several test cases. The first line of input consists of an integer T, indicating the number of test cases. Each test case starts with a line consisting of two integers: N, M, indicating the string's length and the number of Jane's favorite words. Each of the following M lines consists of a favorite word Si. The last line of each test case consists of M integers, while the i-th number indicates the value of Si.

Technical Specification

1. T ≤ 15
2. 0 < N ≤ 50, 0 < M ≤ 100.
3. The length of each word is less than 11 and bigger than 0.
4. 1 ≤ Hi ≤ 100.
5. All the words in the input are different.
6. All the words just consist of 'a' - 'z'.

Output

For each test case, output the string to engrave on a single line.

If there's more than one possible answer, first output the shortest one. If there are still multiple solutions, output the smallest in lexicographically order.

The answer may be an empty string.

Sample Input

2
7 2
love
ever
5 5
5 1
ab
5

Sample Output

lovever
abab

简单翻译一下:给出m个模式串(m≤100),每个模式串有一个权值。先要求构造一个长度不大于n(n≤50)的串使其包含的子模式串的权值和最大。若存在多解,则要求输出长度最小的,若仍存在多解则要求输出字典序最小的。

sol

DP出最大权值应该不难吧

要求字典序最小其实也很好办。开一个string记录路径就行了(string自带比较字典序)。

code

#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const int N = 1500;
int T,n,m,tot,ch[26][N],fail[N],cnt[N],node[101],dp[55][N];
string path[55][N];
char s[N];
queue<int>Q;
void Insert(int k)
{
cin>>s;int l=strlen(s),x=0;
for (int i=0;i<l;i++)
{
if (!ch[s[i]-'a'][x]) ch[s[i]-'a'][x]=++tot;
x=ch[s[i]-'a'][x];
}
node[k]=x;
}
void Get_Fail()
{
for (int i=0;i<26;i++) if (ch[i][0]) Q.push(ch[i][0]);
while (!Q.empty())
{
int u=Q.front();Q.pop();
for (int i=0;i<26;i++)
if (ch[i][u]) fail[ch[i][u]]=ch[i][fail[u]],Q.push(ch[i][u]);
else ch[i][u]=ch[i][fail[u]];
cnt[u]+=cnt[fail[u]];
}
}
void DP()
{
memset(dp,-1,sizeof(dp));
dp[0][0]=0;path[0][0]="";
for (int i=0;i<n;i++)
for (int j=0;j<=tot;j++)
if (dp[i][j]!=-1)
for (int k=0;k<26;k++)
{
int u=ch[k][j];
if (dp[i][j]+cnt[u]>dp[i+1][u])
{
dp[i+1][u]=dp[i][j]+cnt[u];
path[i+1][u]=path[i][j]+(char)(k+'a');
}
else if (dp[i][j]+cnt[u]==dp[i+1][u])
{
string str=path[i][j]+(char)(k+'a');
if (str<path[i+1][u]) path[i+1][u]=str;
}
}
}
int main()
{
cin>>T;
while (T--)
{
cin>>n>>m;
for (int i=0;i<=tot;i++)
{
fail[i]=cnt[i]=0;
for (int j=0;j<26;j++) ch[j][i]=0;
}
tot=0;
for (int i=1;i<=m;i++) Insert(i);
for (int i=1,v;i<=m;i++) cin>>v,cnt[node[i]]+=v;
Get_Fail();
DP();
string str="";int ans=0,maxx=0;
for (int i=1;i<=n;i++)
for (int j=0;j<=tot;j++)
maxx=max(maxx,dp[i][j]);
for (int i=1;i<=n;i++)
{
for (int j=0;j<=tot;j++)
if (dp[i][j]>ans||(dp[i][j]==ans&&path[i][j]<str))
ans=dp[i][j],str=path[i][j];
if (ans==maxx) break;
}
cout<<str<<endl;
}
return 0;
}

[HDU2296]Ring的更多相关文章

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

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

  2. 【AC自动机】【动态规划】hdu2296 Ring

    题解:http://www.cnblogs.com/swm8023/archive/2012/08/08/2627535.html 要输出路径,价值最大优先,价值相同的取长度较小者,仍相同取字典序较小 ...

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

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

  4. HDU2296 Ring(AC自动机 DP)

    dp[i][j]表示行走i步到达j的最大值,dps[i][j]表示对应的串 状态转移方程如下: dp[i][chi[j][k]] = min(dp[i - 1][j] + sum[chi[j][k]] ...

  5. HDU2296 Ring(AC自动机+DP)

    题目是给几个带有价值的单词.而一个字符串的价值是 各单词在它里面出现次数*单词价值 的和,问长度不超过n的最大价值的字符串是什么? 依然是入门的AC自动机+DP题..不一样的是这题要输出具体方案,加个 ...

  6. HDU2296——Ring(AC自动机+DP)

    题意:输入N代表字符串长度,输入M代表喜欢的词语的个数,接下来是M个词语,然后是M个词语每个的价值.求字符串的最大价值.每个单词的价值就是单价*出现次数.单词可以重叠.如果不止一个答案,选择字典序最小 ...

  7. AC自动机基础知识讲解

    AC自动机 转载自:小白 还可参考:飘过的小牛 1.KMP算法: a. 传统字符串的匹配和KMP: 对于字符串S = ”abcabcabdabba”,T = ”abcabd”,如果用T去匹配S下划线部 ...

  8. AC自动机题单

    AC自动机题目 真的超级感谢xzy 真的帮到我很多 题单 [X] [luogu3808][模板]AC自动机(简单版) https://www.luogu.org/problemnew/show/P38 ...

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

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

随机推荐

  1. IOS设备设计完整指南

    作为初学者,常常不知如何下手设计,IOS应用UI设计中碰到的种种基础小问题,在此都将一一得到解答.这份完整的设计指南将带你快速上手,为IOS设计出优雅的应用吧. 关于此设计指南 此设计指南描述的是如何 ...

  2. CentOS 7 安装 Nginx 反向代理 node

    安装 nginx yum install epel-release yum install nginx 配置 nginx sudo vim /etc/nginx/nginx.conf, 改成下面配置: ...

  3. 基于jquery的城市选择插件

    城市选择插件的难度不是很大,主要是对dom节点的操作.而我写的这个插件相对功能比较简答,没有加入省市联动. 上代码好了,参照代码的注释应该比较好理解. /* *基于jquery的城市选择插件 *aut ...

  4. mvc get image 500

    mvc中get图片时报500错误 很奇怪,突然变500错误了,一番查找之后发现原来是因为mimeType重复定义的原因,吐血.. http://stackoverflow.com/questions/ ...

  5. Spring框架系列之AOP思想

    微信公众号:compassblog 欢迎关注.转发,互相学习,共同进步! 有任何问题,请后台留言联系! 1.AOP概述 (1).什么是 AOP AOP 为 Aspect Oriented Progra ...

  6. 判断json是否包含了每个键 PHP

    (1)可以用array_key_exists去判断object对象或array数组中是否含有某个键: (2)不可以用isset去判断判断object对象或array数组中是否含有某个键 $decode ...

  7. Https访问

    Let's Encrypt是很火的一个免费SSL证书发行项目,自动化发行证书,证书有90天的有效期.适合个人使用或者临时使用,不用再忍受自签发证书不受浏览器信赖的提示.去年VPS侦探曾经说过Let's ...

  8. SpringBoot Hello World

    本文首发于我的github博客 前言 SpringBoot是Spring MVC升级版,基于『约定优于配置』的原则,快速开发出web程序. 环境 本系列笔记环境如下: Sun JDK1.8.0_20 ...

  9. Java集合框架(四)—— Queue、LinkedList、PriorityQueue

    Queue接口 Queue用于模拟了队列这种数据结构,队列通常是指“先进先出”(FIFO)的容器.队列的头部保存在队列中时间最长的元素,队列的尾部保存在队列中时间最短的元素.新元素插入(offer)到 ...

  10. thinkpad E480 用户初体验

    梦寐以求的E480终于到手了,经过几天使用之后,也该写一下用户体验了,也算是对这些天的调研的一个总结吧. 首先是外形,从外形上来看E480的外形的确是相对以前的塑料外壳,改进了不少,全金属的机身,磨砂 ...