题目大意:斯蒂文想送给他女盆友一个戒指,并且他想在戒指上刻一些字,他非常了解他女盆友喜欢什么单词,比如"love""forvevr"....并且他还把女盆友喜欢的单词弄了一个高兴度,他现在准备在这个戒指上刻上一个长度不超过N的句子,并且这个句子的高兴度是最大的,如果有多个这样的句子,选择最短的,如果还有多个选择字典序最小的。
 
分析:比较容易想到DP来做,定义数组dp[Ni][kNode],保存第i长度到达k节点的最大价值,然后再用一个数组来保存路径就行了,注意dp数组初始化的时候应该初始化成一个很小的值...在这wa了好多次......................
 
代码如下:
======================================================================================================================================
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std; const int MAXN = ;
const int MAXM = ;
const int MaxSon = ;
const int oo = 1e9+; int dp[MAXM][MAXN];
char path[MAXM][MAXN][MAXM]; struct Ac_Trie
{
int next[MAXN][MaxSon];
int Fail[MAXN], End[MAXN];
int cnt, root; int newnode()
{
for(int i=; i<MaxSon; i++)
next[cnt][i] = -;
Fail[cnt] = End[cnt] = false; return cnt++;
}
void InIt()
{
cnt = ;
root = newnode();
} void Insert(char s[], int val)
{
int now = root; for(int i=; s[i]; i++)
{
int k = s[i]-'a'; if(next[now][k] == -)
next[now][k] = newnode();
now = next[now][k];
} End[now] = val;
}
void GetFial()
{
queue<int>Q;
int now = root; for(int i=; i<MaxSon; i++)
{
if(next[now][i] == -)
next[now][i] = root;
else
{
Fail[next[now][i]] = root;
Q.push(next[now][i]);
}
} while(Q.size())
{
now = Q.front();
Q.pop(); for(int i=; i<MaxSon; i++)
{
if(next[now][i] == -)
next[now][i] = next[Fail[now]][i];
else
{
Fail[next[now][i]] = next[Fail[now]][i];
Q.push(next[now][i]);
}
}
}
}
};
Ac_Trie ac; bool cmp(char a[], char b[])
{
int len_a = strlen(a);
int len_b = strlen(b); if(len_a != len_b)
return len_a > len_b;
return strcmp(a, b) > ;
} int main()
{
int T; scanf("%d", &T); while(T--)
{
int i, j, k, N, M, val;
char s[][];
ac.InIt(); scanf("%d%d", &N, &M); for(i=; i<M; i++)
scanf("%s", s[i]); for(i=; i<M; i++)
{
scanf("%d", &val);
ac.Insert(s[i], val);
} ac.GetFial(); for(i=; i<=N; i++)
for(j=; j<ac.cnt; j++)
dp[i][j] = -oo; memset(path, false, sizeof(path)); char ans[MAXM] = {};
int Max = ;
dp[][] = ; for(i=; i<N; i++)
for(j=; j<ac.cnt; j++)
{
char temp[] = {};
strcpy(temp, path[i][j]);
int len = strlen(temp); for(k=; k<MaxSon; k++)
{
int next = ac.next[j][k];
temp[len] = k+'a'; val = dp[i][j]+ac.End[next]; if(dp[i+][next] < val || (dp[i+][next]==val && cmp(path[i+][next], temp) ) )
{
dp[i+][next] = val;
strcpy(path[i+][next], temp); if(Max < val || (Max==val && cmp(ans, temp)))
{
Max = val;
strcpy(ans, temp);
}
}
}
}
printf("%s\n", ans);
} return ;
}

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

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

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

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

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

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

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

  4. Ring HDU - 2296 AC自动机+简单DP和恶心的方案输出

    题意: 就是现在给出m个串,每个串都有一个权值,现在你要找到一个长度不超过n的字符串, 其中之前的m个串每出现一次就算一次那个字符串的权值, 求能找到的最大权值的字符串,如果存在多个解,输出最短的字典 ...

  5. Lost's revenge - HDU 3341 (自动机+DP)

    题目大意:先给你一些子串,然后给你一个母串,母串里面的字母可以任意调换位置,问最多这个母串经过一些位置变动最多能包含多少个子串.   分析:可以比较明显的看出来的DP,先求出来ATGC分别有多少,然后 ...

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

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

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

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

  8. 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 ...

  9. HDU 2457 DNA repair(AC自动机+DP)题解

    题意:给你几个模式串,问你主串最少改几个字符能够使主串不包含模式串 思路:从昨天中午开始研究,研究到现在终于看懂了.既然是多模匹配,我们是要用到AC自动机的.我们把主串放到AC自动机上跑,并保证不出现 ...

随机推荐

  1. (九)打印机驱动设置—USB接口的设置

    佳博打印机代理商淘宝店https://shop107172033.taobao.com/index.htm?spm=2013.1.w5002-9520741823.2.Sqz8Pf 在此店购买的打印机 ...

  2. linux 命令学习(4)

    Linux中常用的关机和重新启动命令有shutdown.halt.reboot以及init,它们都可以达到关机和重新启动的目的,但是每个命令的内部工作过程是不同的,下面将逐一进行介绍. 1. shut ...

  3. 强大的Core Image框架,各种滤镜处理图像

    首先介绍一下Core Image,他是一个很强大的图像处理框架,他可以让你简单的应用各种滤镜来处理图像,比如说色相,饱和度,亮度等等...他是运用GPU(CPU)实时地处理图像数据和视频的帧.而且Co ...

  4. X3850 Linux 下DSA日志收集办法

    收集工具下载 RHEL 6: 32bit-- [IBM 下载]http://delivery04.dhe.ibm.com/sar/CMA/XSA/03tza/1/ibm_utl_dsa_dsytb7x ...

  5. splice从数组中删除指定定数据

    /*从数组中删除指定定数据var somearray = ["mon", "tue", "wed", "thur"]so ...

  6. cocod2d-x 之 HelloWorld

    cocos2d-x 2.2创建项目 进入cocos2d-x-2.2/tools/project-creator,运行命令 python create_project.py -project MyGam ...

  7. smarty中判断一个变量是否存在于一个数组中或是否存在于一个字符串中?

    smarty支持php的系统函数可以直接使用{if in_array($str, $arr) || strpos($str, $string)} yes {else} no{/if}

  8. Html5游戏框架createJs的简单用法

    声明:本文为原创文章,如需转载,请注明来源WAxes,谢谢!http://www.it165.net/pro/html/201403/11105.html 楼主记忆力不好,最近刚好用了一下create ...

  9. JS拖动div的原理

    要实现移动窗体,首先要捕获三个参数:1.a = 鼠标点击时的坐标.2.b = 被移动窗体的左顶点坐标.3.c = 鼠标移动时的坐标.然后还要算出你鼠标无论点击窗体哪个位置,移动改变的都是 (d = 窗 ...

  10. 《30天自制操作系统》读书笔记(5) GDT&IDT

    梳理项目结构 项目做到现在, 前头的好多东西都忘了, 还是通过Makefile重新理解一下整个项目是如何编译的: 现在我们拥有这么9个文件: ipl10.nas    InitialProgramLo ...