题目大意:斯蒂文想送给他女盆友一个戒指,并且他想在戒指上刻一些字,他非常了解他女盆友喜欢什么单词,比如"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. 修改docker默认172.17网段

    docker启动时默认使用172.17.x.x作为容器的ip地址,可以通过以下方法自定义该网段: sudo service docker stop通过命令route -n查看docker0是否存在,若 ...

  2. For Me ...

    一直有做博客的打算,但是这也看不上,那也看不上. 总想着做一个personal blog,界面,风格全由自己设计. 可时间上总是不充裕的. 可技术上总是欠火候的. 可内容上总是待斟酌的. 于是时间被我 ...

  3. (JAVA)从零开始之--打印流PrintStream记录日志文件

    这里的记录日志是利用打印流来实现的. 文本信息中的内容为String类型.而像文件中写入数据,我们经常用到的还有文件输出流对象FileOutputStream. File file = new Fil ...

  4. 解决 dyld: Library not loaded:Reason: image not found

    在使用第三方framework时,直接把framework拖到项目中,运行时报错: dyld: Library not loaded: @rpath/ZipZap.framework/ZipZap R ...

  5. 子元素的margin-top影响父元素原因和解决办法

    这个问题会出现在所有浏览器当中,原因是css2.1盒子模型中规定, In this specification, the expression collapsing margins means tha ...

  6. G - A+B for Input-Output Practice (VI)

      Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u   Description You ...

  7. Oracle数据库基础知识_字符串操作相关2

    6.LPAD,RPAD 作用:左/右边的字符串填充一些特定的字符语法: LPAD(string , n, [pad_String])          string:可是字符或者参数          ...

  8. ThinkPHP 3.2 模板使用函数

    {$name|md5|strtoupper|substr=0,3} 编译后的结果是: <?php echo (substr(strtoupper(md5($name)),0,3));?> ...

  9. android.support.v7.widget.Toolbar 中menu图标不显示问题

    <?xml version="1.0" encoding="utf-8"?><menu xmlns:android="http:// ...

  10. 为Ubuntu配置ssh服务 方便远程登陆

    Ubuntu系统必须开启ssh服务后,XP或者其他的主机才可以远程登陆到Ubuntu系统. 1,安装软件包,执行sudo apt-get install openssh-server Ubuntu缺省 ...