HDU-2296 Ring(AC自动机+DP)
题目大意:给出的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)的更多相关文章
- HDU 2296 Ring [AC自动机 DP 打印方案]
Ring Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submissio ...
- HDU 2296 Ring -----------AC自动机,其实我想说的是怎么快速打印字典序最小的路径
大冥神的代码,以后能贴的机会估计就更少了....所以本着有就贴的好习惯,= =....直接贴 #include <bits/stdc++.h> using LL = long long ; ...
- HDU2296 Ring —— AC自动机 + DP
题目链接:https://vjudge.net/problem/HDU-2296 Ring Time Limit: 2000/1000 MS (Java/Others) Memory Limit ...
- HDU 2296 Ring ( Trie图 && DP && DP状态记录)
题意 : 给出 m 个单词,每一个单词有一个权重,如果一个字符串包含了这些单词,那么意味着这个字符串拥有了其权重,问你构成长度为 n 且权重最大的字符串是什么 ( 若有权重相同的,则输出最短且字典序最 ...
- 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]] ...
- 对AC自动机+DP题的一些汇总与一丝总结 (2)
POJ 2778 DNA Sequence (1)题意 : 给出m个病毒串,问你由ATGC构成的长度为 n 且不包含这些病毒串的个数有多少个 关键字眼:不包含,个数,长度 DP[i][j] : 表示长 ...
- hdu 2296 aC自动机+dp(得到价值最大的字符串)
Ring Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- HDU 2425 DNA repair (AC自动机+DP)
DNA repair Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- 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 ...
随机推荐
- Python学习笔记-抽象
懒惰即美德.代码量少. hasattr判断函数是否可用. 创建函数. def hello(name) return 'hello,'+name+'!' 文档化函数: 加注释(#开头) 文档字符串.函数 ...
- 基于Jenkins + Git的PHP项目编译脚本
本文针对的是了解或已经在使用Jenkins和Git的开发者或团队. 本团队使用了Jenkins作为持续集成平台,Git作为版本管理工具,而本人负责的项目是PHP项目,所谓发布项目就是复制文件. 通常有 ...
- 颜色代码表#FFFFFF #FF0000 #00FF00 #FF00FF (2015-07-21 10:39)转载
▼标签: 颜色代码表 白色 ffffff 红色 ff0000 黑色 000000 it 分类: hht1 白色 #FFFFFF 2 红色 #FF0000 3 绿色 #00FF00 4 蓝色 # ...
- (转)整体把握jQuery -jQuery 的原型关系图
整体把握jQuery -jQuery 的原型关系图 (原)http://www.html5cn.org/article-6529-1.html 2014-7-2 17:12| 发布者: html5cn ...
- firefox浏览器中silverlight无法输入问题
firefox浏览器中silverlight无法输入问题 今天用firefox浏览silverlight网页,想在文本框中输入内容,却没想到silverlight插件意外崩溃了.google一下,发现 ...
- MyBatis 配置文件头部换行异常
INFO - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory ...
- vim 分屏显示
我用vim打开一个文件后,想同时打开另一个文件,就像windows中打开两个记事本一样,因此需要分屏显示 首先用vim打开一个文件 vim file1 输入命令[Esc] :sp file2 分屏打开 ...
- Angularjs select的使用
实例一:基本下拉效果 usage: label for value in array <!-- lang: html --> <select ng-model="selec ...
- 采用OLEDB数据库方式向指定的Excel添加数据,怪像!
我们都知道,对Excel进行操作,其实方法是多种多样的,例如采用Office.Interop;例如采用ASPCell:例如采用NPOI:再例如采用数据库连接的方式OLEDB,etc. 还是先说说背景吧 ...
- PC端和手机访问调用不同的页面,JS和PHP不同方法
js方法: var urlqr = location.href; urlqr = urlqr.replace(/iphoneF_/, "pc")这里写正则替换页面地址 if( ...