6360: 词韵

时间限制: 2 Sec  内存限制: 128 MB
提交: 136  解决: 19
[提交] [状态] [讨论版] [命题人:admin]

题目描述

Adrian 很喜欢诗歌中的韵。他认为,两个单词押韵当且仅当它们的最长公共 后缀的长度至少是其中较长单词的长度减一。也就是说,单词 A 与单词 B 押韵 当且仅当 LCS(A, B) ≥ max(|A|, |B|) – 1。(其中 LCS 是最长公共后缀 longest common suffix 的缩写)
现在,Adrian 得到了 N 个单词。他想从中选出尽可能多的单词,要求它们能 组成一个单词序列,使得单词序列中任何两个相邻单词是押韵的。

输入

第一行是一个整数N。
接下来N行,每行一个由小写英文字母组成的字符串,表示每个单词。所有单词互不相同。

输出

输出一行,为一个整数,表示最长单词序列的长度。

样例输入

5
ask
psk
k
krafna
sk
​

样例输出

4

提示

一种最长单词序列是 ask-psk-sk-k。
30%的测试数据:1 ≤ N ≤ 20,所有单词长度之和不超过 3 000。
100%的测试数据:1 ≤ N ≤ 500 000,所有单词长度之和不超过 3 000 000。

一定要先写一波收获,首先,链式前向星来建字典树成功取代我的数组模板,便于查询,节省空间。然后是树上DP,想啊想啊想,想了好久才知道为什么要维护最长链和次长链,DP跑的也是云里雾里,最关键的是这么折磨人的题,我竟然看了一天,看着题解的前提下,看了一天。。。。。。

问题要求后缀相同的前提下,LSA比最长串至多少一,容易想到的是将字符串翻转,建立字典树,问题就变成了在字典树上,找一条链,使得这条链上的符合要求的单词最多,为了方便遍历,用链式前向星建树,剩下的就是煎熬的DP。

可以看出,若是想要满足题目的要求,表现在字典树上就是当前节点的孩子节点和父亲节点才有可能构成,之所以有可能是因为当他的父节点和子节点都是单词的时候才成立。判断是否是单词可以在建字典树的过程中维护,然后就是找父节点和子节点,当然只需要维护子节点就可以,那么要如何维护子节点才能保证答案正确呢。我们可以发现 在字典树上,他所有的孩子节点都是满足要求的,而且不存在相同单词,所以每个单词只要进行一次计数。那么对于当前节点来说,他的最大值就是所有的孩子节点的数量加上孩子中拥有最长链和次长链的孩子的数量和,因为孩子之间已经存在一个单词的差异,我们要选择两个最长链的孩子,这样得到的结果才是最优情况。

然后就是dfs遍历树,找到每个孩子节点应有的链上的单词数,若当前节点是单词,则其子节点可以不用是单词,若当前节点不是单词,那对于他后面所构成的链对结果没有贡献,返回0即可。

需要注意的是此算法并不适合有重复单词的情况,队友的这种作法无视重复单词。传送门:https://blog.csdn.net/winter2121/article/details/81213624

代码实现:

/*
Look at the star
Look at the shine for U
*/ #include<bits/stdc++.h>
#define sl(x) scanf("%lld",&x)
using namespace std;
typedef long long ll;
const int N = 7e5+5;
const ll mod = 1e9+7;
const ll INF = 1e18;
struct node{int v,next,w;
}p[N];
int cnt = 1,head[N],vis[N];
char s[N];void add(int u,int v)
{p[++cnt].v = v;p[cnt].next = head[u];head[u] = cnt;
}void build(char *s)
{int u = 1, n = strlen(s);for(int i = n-1;i >= 0;i--){int ch = s[i] - 'a';int temp = 0;for(int j = head[u]; ~j; j = p[j].next) if(p[j].v == ch) {temp = 1;u = j;break;}if(!temp) {add(u,ch);u = cnt;}}vis[u] = 1;
}
int dp[N][2];
void dfs(int u)
{int i,j,k,mx1 = -1,mx2 = -1,sum = vis[u];for(i = head[u];~i;i = p[i].next){dfs(i); sum += vis[i]; int t = dp[i][1]-vis[i];if(t > mx1) {mx2 = mx1;mx1 = t;}else if (t > mx2) mx2 = t;}if(mx1 >= 0 && mx2 >= 0) dp[u][0] = mx1+mx2+sum;if(vis[u]) dp[u][1] = sum+(mx1 > 0?mx1 : 0);
}int main()
{int n,i,j,k;scanf("%d",&n);for(i = 0;i < N ;i++)head[i] = -1;for(i = 0;i < n;i++){scanf("%s",s);build(s);}dfs(1);int ans = 0;for(i = 0;i <= cnt;i++) {int t = max(dp[i][0],dp[i][1]);ans = max(ans,t);}printf("%d\n",ans);
}

词韵 (字典树+树形DP)相关推荐

  1. C++解题报告——Rima(字典树+树形DP)

    题目描述 Adrian对单词押韵很感兴趣.如果两个单词的最长公共后缀的长度与两个单词中较长那个的长度一样,或者等于较长单词的长度减一,则这两个单词押韵.换句话说,如果A,B的最长公共后缀LCS(A,B ...

  2. 6360: 词韵(字典树,DP)

    6360: 词韵 时间限制: 2 Sec  内存限制: 128 MB 提交: 171  解决: 31 [提交] [状态] [讨论版] [命题人:admin] 题目描述 Adrian 很喜欢诗歌中的韵. ...

  3. [WC2018]通道——边分治+虚树+树形DP

    题目链接: [WC2018]通道 题目大意:给出三棵n个节点结构不同的树,边有边权,要求找出一个点对(a,b)使三棵树上这两点的路径权值和最大,一条路径权值为路径上所有边的边权和. 我们按照部分分逐个 ...

  4. [APIO2018]铁人两项——圆方树+树形DP

    题目链接: [APIO2018]铁人两项 对于点双连通分量有一个性质:在同一个点双里的三个点$a,b,c$,一定存在一条从$a$到$c$的路径经过$b$且经过的点只被经过一次. 那么我们建出原图的圆方 ...

  5. UVALive 3942 Remember the Word(字典树+DP)

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...

  6. P2607-[ZJOI2008]骑士【基环树,树形dp】

    正题 题目大意 每个骑士有一个不可以同时上场的骑士,和一个战斗力.求最大战斗力. 解题思路 类似没有上司的舞会 其实就是在基环树森林,我们可以利用二次树形dp的方法. 先找到环,然后强行将环断开进行一 ...

  7. BZOJ 2286 消耗战 (虚树+树形DP)

    给出一个n节点的无向树,每条边都有一个边权,给出m个询问, 每个询问询问ki个点,问切掉一些边后使得这些顶点无法与顶点1连接. 最少的边权和是多少. (n<=250000,sigma(ki)&l ...

  8. BZOJ5419[Noi2018]情报中心——线段树合并+虚树+树形DP

    题目链接: [NOI2018]情报中心 题目大意:给出一棵n个节点的树,边有非负边权,并给出m条链,对于每条链有一个代价,要求选出两条有公共边的链使两条链的并的边权和-两条链的代价和最大. 花了一天的 ...

  9. bzoj 3611: [Heoi2014]大工程(虚树+树形DP)

    3611: [Heoi2014]大工程 Time Limit: 60 Sec  Memory Limit: 512 MB Submit: 1697  Solved: 718 [Submit][Stat ...

最新文章

  1. Matlab编程与数据类型 -- 多维数组
  2. keepalived mysql集群_keepalived + Mysql(主主)实现高可用集群
  3. tar -xf_青铜表选什么?不可错过的XF帝舵碧湾小铜盾
  4. pandas 提取股票价格
  5. 解决vs2010下不能创建项目及文件的问题
  6. Android 默认Tab标签大小及间距修改
  7. Asp.Net Core 5 REST API - Step by Step(一)
  8. Spring Data Solr教程:将自定义方法添加到单个存储库
  9. egg 编码规范_Egg 框架简述 (仅学习)
  10. Visual Studio 2012安装VASSISTX插件后导致CPU高的解决的方法
  11. JAVA程序设计 实验一报告
  12. JS前端怎样通过程序来获取当前浏览器是什么版本的浏览器(或者判断当前浏览器是否为IE8及以下浏览器)
  13. 盘点丨12款数据库建模工具特点,总有一款适合你!
  14. 手把手教你用 Keras 实现 LSTM 预测英语单词发音
  15. 服务器文档分类,服务器的分类
  16. 一种基于STM32F1 MCU的增量型编码器测速的方法
  17. vue判断当前浏览器为IE低版本,给出升级提示;IE11及其他浏览器正常使用
  18. jsp页面获取到后台的cookie(记住我)
  19. win10开机占用内存大,资源管理器也看不到运行进程
  20. Qualcomm QCC 蓝牙芯片烧录工具

热门文章

  1. 《Python程序设计(第3版)》[美] 约翰·策勒(John Zelle) 第 2 章 答案
  2. Java基础编程练习50题(转载)
  3. 软件质量保证与测试作业(一)---- 什么是图灵测试
  4. 【重要】原淘宝 npm 域名已更新
  5. 用选择法对10个整数进行升序排序
  6. txt转azw3软件在线转换有哪些?快把这些软件收好
  7. 库卡KUKA-MoveJ()/MoveL()-运动程序-私有库
  8. tm影像辐射定标_ENVI-专题五 Landsat TM辐射定标与大气纠正
  9. 【数据库】SQL语言
  10. 小红书流量逻辑、KOL模型、内容营销|2022千瓜历年研究汇总