题目大意:斯蒂文想送给他女盆友一个戒指,并且他想在戒指上刻一些字,他非常了解他女盆友喜欢什么单词,比如"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. hadoop-0.20-集群搭建___实体机通过SSH访问基于VM安装的Linux

    不得不说LZ在最开始搭建hadoop的时候,由于VM中的网段配置和本地IP地址没有配置好, 所以一直都在使用 VM的共享文件夹的功能, 以至于集群搭建好之后,只有namenode主机可以实现共享的功能 ...

  2. 【转】 UITableViewCell的标记、移动、删除、插入

    原文: http://blog.csdn.net/duxinfeng2010/article/details/7725897 这篇文章是建立在 代码实现 UITableView与UITableView ...

  3. 非注解SpringMVC

    <!-- SpringMVC前端控制器 --> <servlet> <servlet-name>springmvc</servlet-name> < ...

  4. 使用IDEA,利用SpringMVC框架建立HelloWorld项目

    无论是从头开始学习一门新的语言还是技术,我们的入门都是从HelloWorld开始,也许就是因为这样,我在学习Spring MVC的时候,就有一种偏执,一定要写出一个HelloWorld来.研究了好久, ...

  5. jQuery实现公告文字左右滚动的代码。

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. Node.js的长连接

    之前写的js服务器脚本,在服务器上运行的挺好的.也经过了压力测试,单次接受4000次的连接不成问题.在5s里,可以应答1W多次的连接.对于这个连接次数,我们还是挺满意的,但是Boss说:客户端每2分钟 ...

  7. Perl 中级教程 第5章课后习题

    5. 9. 1. 练习1 [5 分钟] 先不要运行程序, 看看你能否判断出这程序的哪部份出了问题?如果你看不出 来, 就可以运行一相程序, 得到些暗示, 来看是否能修改好: my %passenger ...

  8. 利用set实现去重

    最近读了一些有关于ES6的文章,觉得真是一个超级大的进步,就是不知道兼容性怎么样,鉴于我还在初学,先写个小例子练手,顺便时刻提醒自己要坚持学下去.未来的趋势肯定是替代es5没跑了. var arr=[ ...

  9. Canvas中点到点的路径运动

    /*随机生成两个点,然后以两点为端点,进行运动,主要使用了SetInterval,对画布进行不断的擦除描绘的操作*/1 <!DOCTYPE html> <html xmlns=&qu ...

  10. js 表达式与运算符 详解(下)

    比较运算符: > .>= .<. <=.  ==. !=. ===. !==. 比较运算符的结果都为布尔值 ==只比较值是否相等    而    ===比较的是值和数据类型都要 ...