题目大意:给出的m个字符串都有一个权值。用小写字母构造一个长度不超过n的字符串S,如果S包含子串s,则S获取s的权值。输出具有最大权值的最小字符串S。

题目分析:先建立AC自动机。定义状态dp(step,u)表示长度为step、在u节点上的最大权值。状态转移方程为:dp(step,u)=max(dp(step-1,v)+w(u))。其中,v为能到达u的前一个节点。

代码如下:

# include<iostream>
# include<cstdio>
# include<queue>
# include<string>
# include<cstring>
# include<algorithm>
using namespace std; int cnt;
int ch[1200][26];
int fail[1200];
int val[1200];
int w[105]; void init()
{
cnt=0;
memset(ch,-1,sizeof(ch));
memset(val,0,sizeof(val));
} int idx(char c)
{
return c-'a';
} void insert(char *s,int key)
{
int len=strlen(s);
int r=0;
for(int i=0;i<len;++i){
int c=idx(s[i]);
if(ch[r][c]==-1) ch[r][c]=++cnt;
r=ch[r][c];
}
val[r]=w[key];
} void getFail()
{
queue<int>q;
fail[0]=0;
for(int i=0;i<26;++i){
if(ch[0][i]==-1)
ch[0][i]=0;
else{
fail[ch[0][i]]=0;
q.push(ch[0][i]);
}
}
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=0;i<26;++i){
if(ch[u][i]==-1)
ch[u][i]=ch[fail[u]][i];
else{
fail[ch[u][i]]=ch[fail[u]][i];
q.push(ch[u][i]);
}
}
}
} char h[105][15];
int dp[55][1200];
string path[55][1200]; bool isSmall(string s,string t)
{
if(t=="") return true;
if(s.size()<t.size()) return true;
if(s.size()>t.size()) return false;
return s<t;
} string DP(int n)
{
memset(dp,-1,sizeof(dp));
dp[0][0]=0;
for(int i=0;i<=n;++i) for(int j=0;j<=cnt;++j)
path[i][j]="";
int fen=0;
for(int i=0;i<=n;++i){
for(int j=0;j<=cnt;++j){
if(dp[i][j]==-1) continue;
for(int c=0;c<26;++c){
if(dp[i+1][ch[j][c]]<dp[i][j]+val[ch[j][c]]){
dp[i+1][ch[j][c]]=dp[i][j]+val[ch[j][c]];
path[i+1][ch[j][c]]=path[i][j]+(char)('a'+c);
}else if(dp[i+1][ch[j][c]]==dp[i][j]+val[ch[j][c]]){
if(isSmall(path[i][j]+(char)('a'+c),path[i+1][ch[j][c]]))
path[i+1][ch[j][c]]=path[i][j]+(char)('a'+c);
}
}
if(i>0) fen=max(fen,dp[i][j]);
}
}
if(fen==0) return "";
string res="";
for(int i=1;i<=n;++i) for(int j=0;j<=cnt;++j){
if(dp[i][j]==fen&&isSmall(path[i][j],res)){
res=path[i][j];
}
}
return res;
} int main()
{
int T,n,m;
scanf("%d",&T);
while(T--)
{
init();
scanf("%d%d",&n,&m);
for(int i=0;i<m;++i)
scanf("%s",h[i]);
w[0]=0;
for(int i=1;i<=m;++i)
scanf("%d",w+i);
for(int i=0;i<m;++i)
insert(h[i],i+1);
getFail();
cout<<DP(n)<<endl;
}
return 0;
}

HDU-2296 Ring(AC自动机+DP)的更多相关文章

  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自动机,其实我想说的是怎么快速打印字典序最小的路径

    大冥神的代码,以后能贴的机会估计就更少了....所以本着有就贴的好习惯,= =....直接贴 #include <bits/stdc++.h> using LL = long long ; ...

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

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

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

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

  5. 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]] ...

  6. 对AC自动机+DP题的一些汇总与一丝总结 (2)

    POJ 2778 DNA Sequence (1)题意 : 给出m个病毒串,问你由ATGC构成的长度为 n 且不包含这些病毒串的个数有多少个 关键字眼:不包含,个数,长度 DP[i][j] : 表示长 ...

  7. hdu 2296 aC自动机+dp(得到价值最大的字符串)

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

  8. HDU 2425 DNA repair (AC自动机+DP)

    DNA repair Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  9. HDU 3341 Lost's revenge AC自动机+dp

    Lost's revenge Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)T ...

随机推荐

  1. Asp.net MVC路由机制

    C:/Windows/Microsoft.NET/Framwork/v4.0.30319/config/web.config-> httpModules-> System.Web.Rout ...

  2. mac idea中 maven项目添加的时候没有java文件

    file --other setting --maven  选中第二项即可  apply下

  3. 如何使用.NET开发全版本支持的Outlook插件产品(一)——准备工作

    这半年一直在做Outlook的插件,因为不会VC++,所以想找一款基于.NET,用C#开发Outlook插件的技术方案.没想到,光技术选型这件事,就用各种技术手段验证了将近一个月,还花费了大量的精力做 ...

  4. c++ 基础一

    // my first program in C++ #include <iostream.h> using namespace std; int main() { cout <&l ...

  5. Mac上安装与更新Ruby,Rails运行环境

    Mac安装后就安装Xcode是个好主意,它将帮你安装好Unix环境需要的开发包,也可以独立安装command_line_tools_for_xcode 1.安装RVM RVM:Ruby Version ...

  6. js①

    JavaScript的引入方式 直接在script标签内部书写代码 ```html <!DOCTYPE html> ``` 2. 通过script标签的src属性,引入外部的JavaScr ...

  7. Python开发入门与实战13-基于模板的界面

    13. 基于模板的界面 本章我们将继续基于库存的简单例子来阐述如何在python django中体现MVC的架构,根据djangobook说明: M:数据存取部分,由django数据库层处理,本章要讲 ...

  8. SQL Server 简介

    什么是数据库? 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库.是以一定方式储存在一起.能为多个用户共享.具有尽可能小的冗余度的特点.是与应用程序彼此独立的数据集合. SQL S ...

  9. 学习linux/unix编程方法的建议(转)

    假设你是计算机科班出身,计算机系的基本课程如数据结构.操作系统.体系结构.编译原理.计算机网络你全修过 我想大概可以分为4个阶段,水平从低到高从安装使用=>linux常用命令=>linux ...

  10. Android动画之Tween动画实战

    Android动画分为Tween动画和Frame动画,上一节通过一个实例介绍了Frame动画,本节将介绍Tween动画.Tween可以把对象进行缩小.放大.旋转和渐变等操作.     Tween动画有 ...