题目是给几个带有价值的单词。而一个字符串的价值是 各单词在它里面出现次数*单词价值 的和,问长度不超过n的最大价值的字符串是什么?

依然是入门的AC自动机+DP题。。不一样的是这题要输出具体方案,加个字符数组记录每个状态最优情况的字符串即可。

另外题目字典序是先考虑长度再考虑每一位单词;特别要注意,有一个非常坑的地方看了Disscus才知道——单词A包含单词B,那么只计算单词A不计算单词B。

  • dp[i][j]表示长度i(自动机上转移k步)后缀状态是自动机第j个结点的字符串的最大价值
  • dp[0][0]=0
  • 我为人人,dp[i][j]向26个字母转移到dp[i'][j']
 #include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int tn,ch[][],fail[],val[];
void insert(char *s,int a){
int x=;
for(int i=; s[i]; ++i){
int y=s[i]-'a';
if(ch[x][y]==) ch[x][y]=++tn;
x=ch[x][y];
}
val[x]+=a;
}
void init(){
memset(fail,,sizeof(fail));
queue<int> que;
for(int i=; i<; ++i){
if(ch[][i]) que.push(ch[][i]);
}
while(!que.empty()){
int x=que.front(); que.pop();
for(int i=; i<; ++i){
if(ch[x][i]) que.push(ch[x][i]),fail[ch[x][i]]=ch[fail[x]][i];
else ch[x][i]=ch[fail[x]][i];
//val[ch[x][i]]+=val[ch[fail[x]][i]];
}
}
}
char str[][];
int d[][];
char path[][][];
int main(){
int t,n,m,a;
scanf("%d",&t);
while(t--){
tn=;
memset(ch,,sizeof(ch));
memset(val,,sizeof(val));
scanf("%d%d",&n,&m);
for(int i=; i<m; ++i) scanf("%s",str[i]);
for(int i=; i<m; ++i){
scanf("%d",&a);
insert(str[i],a);
}
init();
memset(path,,sizeof(path));
memset(d,-,sizeof(d));
d[][]=;
for(int i=; i<n; ++i){
for(int j=; j<=tn; ++j){
if(d[i][j]==-) continue;
for(int k=; k<; ++k){
int &nd=d[i+][ch[j][k]];
if(nd<d[i][j]+val[ch[j][k]]){
nd=d[i][j]+val[ch[j][k]];
strcpy(path[i+][ch[j][k]],path[i][j]);
path[i+][ch[j][k]][i]=k+'a';
}else if(nd==d[i][j]+val[ch[j][k]]){
char tmp[]={};
strcpy(tmp,path[i][j]);
tmp[i]=k+'a';
if(strcmp(tmp,path[i+][ch[j][k]])<) strcpy(path[i+][ch[j][k]],tmp);
}
}
}
}
int resi=,resj=;
for(int i=; i<=n; ++i){
for(int j=; j<=tn; ++j){
if(d[resi][resj]<d[i][j]) resi=i,resj=j;
else if(d[resi][resj]==d[i][j] && resi==i && strcmp(path[resi][resj],path[i][j])>) resi=i,resj=j;
}
}
puts(path[resi][resj]);
}
return ;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  8. POJ1625 Censored!(AC自动机+DP)

    题目问长度m不包含一些不文明单词的字符串有多少个. 依然是水水的AC自动机+DP..做完后发现居然和POJ2778是一道题,回过头来看都水水的... dp[i][j]表示长度i(在自动机转移i步)且后 ...

  9. HDU2457 DNA repair(AC自动机+DP)

    题目一串DNA最少需要修改几个基因使其不包含一些致病DNA片段. 这道题应该是AC自动机+DP的入门题了,有POJ2778基础不难写出来. dp[i][j]表示原DNA前i位(在AC自动机上转移i步) ...

随机推荐

  1. 修改 ~/.bashrc显示 git 当前分支

    vim ~/.bashrc # git branch show configuration PS1="\\w:\$(git branch 2>/dev/null | grep '^*' ...

  2. node.js+websocket实现简易聊天室

    (文章是从我的个人主页上粘贴过来的,大家也可以访问我的主页 www.iwangzheng.com) websocket提供了一种全双工客户端服务器的异步通信方法,这种通信方法使用ws或者wss协议,可 ...

  3. Kalendar server Beijing Tiandiyuandian Technology Limited 果然是木马

    我的Windows 7 系统,在开始菜单里面输入msconfig ,回车打开系统配置,隐藏所有Microsoft的进程,在服务和启动项里面都有 Kalendar server   Beijing Ti ...

  4. HDOJ 1878 欧拉回路 nyoj 42一笔画问题

    #include<cstdio> #include<cstring> ]; int find(int x) { if(visited[x]!=x) return find(vi ...

  5. Mac 下 Chrome 浏览器 快捷键

    ⌘-Option-I 打开“开发人员工具”. ⌘-Option-J 打开“JavaScript 控制台”. ⌘-Option-U 打开当前网页的源代码. 转自: http://www.harbin-s ...

  6. NSUrlConnection 和 NSUrlRequest 的关系

    开始看到这2个名字,总感觉NSUrlConnection才是主要的网络请求类,其实不是,先看官方文档 An NSURLConnection object lets you load the conte ...

  7. Android 向Application对象添加Activity监听

    可以建立对象把Application.ActivityLifecycleCallbacks接口中的函数实现,并利用public void registerActivityLifecycleCallba ...

  8. typedef和#define

    typedef:在计算机编程语言中用来为复杂的声明定义简单的别名(给类型起别名,整体类型替换),它本身是一种存储类的关键字,与auto.extern.mutable.static.register等关 ...

  9. 获取Assets目录下的图片并显示

    package com.jingle.getlocal; import java.io.InputStream; import android.app.Activity; import android ...

  10. Android之事件分发机制

    本文主要包括以下内容 view的事件分发 viewGroup的事件分发 首先来看两张图 在执行touch事件时 首先执行dispatchTouchEvent方法,执行事件分发. 再执行onInterc ...