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 ...
随机推荐
- ThinkPHP(3)SQL查询语句
ThinkPHP中对查询语句,包含了基本的查询方式.表达方式.快速查询.区间查询.组合查询.SQL查询.动态查询和子查询. 一.查询方式 ThinkPHP提供了三种基本的查询方式:字符串条件查询.索引 ...
- 为什么 input 元素能用 width 属性
前几天在是写网页的时候发现input可以设置宽高,很疑惑,上网查了之后发现: 简单的认为 input 就是 inline 元素是片面的.元素默认以何种 display 属性值显示出来,这个其实更多的时 ...
- 几款Z2760平板对比
现阶段的Windows平板本质上分为Windows RT系统平板和完整的Windows 8系统平板两大阵营.RT系统的平板轻薄续航持久,但是由于没法安装常规的.exe程序,所以对于工作需要略显不足,是 ...
- C++的默认构造函数与构造函数
今天看书,忽然发现自己对默认构造函数/构造函数的理解很模糊,在实际项目中写类时,这些细节问题并没有涉及到.因此,就专门对着<C++ Primer Plus>将默认构造函数/构造函数这一块简 ...
- Python学习之运算符
Python运算符 算术运算符 运算符 描述 + 相加 - 相减 * 相乘 / 相除 % 取模 ** 幂 // 整除 比较运算符 运算符 描述 == 等于 != 不等于 <> 不等于 &g ...
- 用jQuery做一个三级菜单,鼠标移动到二级菜单的选项上,然后再迅速离开后,当鼠标再移动到该一级菜单或其他二级菜单选项,三级菜单也会显示。
用jQuery做一个三级菜单,鼠标移动到二级菜单的选项上,然后再迅速离开后,当鼠标再移动到该一级菜单或其他二级菜单选项,三级菜单也会显示. 原因:在为一个元素绑定hover事件之后,用户把光标移入元素 ...
- selected 刷新页面后selected选中的值保持不表(thinkphp 从控制器assign 传值到js)
昨晚解决select 刷新页面以后选择的值保持不变,要想让seleted不变,有两种思路, 1,在提交表单的时候,将所选择的option的属性设为checked . 2.将option的value或者 ...
- matlab mesh visualization
1. matlab color specification http://au.mathworks.com/help/matlab/ref/colorspec.html
- matlab中的数据结构
一.cell 1. function: num2cell(A,n) n表示如何把A中的数据转换为cell. n=1表示把每列的所有行转换为cell:n=2表示把每行的所有列转换为cell. >& ...
- Could not find result map com.lrlz.weixin.dao.SysUserDAO.SysUser
<select id="selectByTimeCount" resultType="java.lang.Integer" parameterType=& ...