【SCOI2016】背单词
P3294【SCOI2016】背单词
【提示】
这道题大概是告诉我们,让我们用一堆n个单词安排顺序,如果当前位置为x,当前单词的后缀没在这堆单词出现过,代价就为x,这里的后缀是原意,但不算自己(不算本身的后缀【如果用集合来说就是真子集】),举个例子比如abc的后缀是bc和c但是它的后缀不包括它本身。
否则如果它的后缀(指在n个单词中的)在1~x-1全部出现了,代价为x减去最后一个后缀的位置y,如果没有全部出现,代价就为n^2,我们可以很显然的发现这个吃泡椒的数量是根据这个后缀来决定的,所以我们要尽量将所有的背当前的单词吃的泡椒数目变得最小时,吃泡椒的总数就会最小,那么我们就需要让背当前的单词时,吃的泡椒的类型是y-x类型的,因为只有这样才能满足最小。
我们可以发现按后缀建字典树,然后直接按子树大小贪心使其被每一个单词吃的泡椒数最少,然后直接一个贪心+字典树就可以过了这道题。
但是我一开始偷懒就直接在字典树上贪心走子树,这样是不行的,吃泡椒的数量的大小是错误的,我们得把关键点树给建出来然后再做,只有这样我们才能将这题A掉。
题解
直接来讲正确的解法:
首先可以发现一定要保证放每个点前它的后缀一定已经被放了(可以根据之前说的要使每个单词的吃的泡椒数最少【贪心的思路】来理解这个东西),所以我们可以根据这个把所有的串倒着插入我们建的字典树当中,然后答案一定是类似于这个样子的:一个串->若干以这个串为后缀的串。
那么按照怎样的插入顺序插入会更优呢? 可以发现先插入儿子较少的串答案会更优 那么我们就只需要把这棵字典树重构一下,去掉所有的无效节点,只留下代表某个点的结尾的节点 然后每次都是贪心的按照儿子从少到多的节点的顺序Dfs即可,这样就行了。
#include <bits/stdc++.h>//万能头文件
#define ll long long//宏定义long long
using namespace std;//运用命名空间std
const int N=6e5+10;//根据数据范围给出n的最大值
vector <int> Edge[N];//定义一个可变的数组
char s[N];
int ch[N][26],endro[N],tot;
int n,clock=-1,siz[N];
ll ans;
void ins()//初始化,将字母转换成数字存储
{
scanf("%s",s+1);//下标从一开始
int now=0,len=strlen(s+1);
for(int i=len;i;i--)
{
int c=s[i]-'a';
if(!ch[now][c]) ch[now][c]=++tot;
now=ch[now][c];
}
endro[now]=1;
}
void dfs0(int now,int anc)
{
if(endro[now]) Edge[anc].push_back(now),anc=now;
for(int i=0;i<26;i++)
if(ch[now][i])
dfs0(ch[now][i],anc);
}
void dfs(int now)//按照儿子从少到多的节点的顺序的贪心的Dfs
{
siz[now]=1;
for(int i=0;i<Edge[now].size();i++)
dfs(Edge[now][i]),siz[now]+=siz[Edge[now][i]];
}
bool cmp(int x,int y){return siz[x]<siz[y];}
void dfs(int now,int las)
{
int tim=++clock;
ans=ans+tim-las;
std::sort(Edge[now].begin(),Edge[now].end(),cmp);
for(int i=0;i<Edge[now].size();i++)
dfs(Edge[now][i],tim);
}
int main()//主函数
{
scanf("%d",&n);//n个单词
for(int i=1;i<=n;i++) ins();
dfs0(0,0);
dfs(0);
dfs(0,0);
printf("%lld\n",ans);//输出吃泡椒的总数
return 0;//结束程序
}
【SCOI2016】背单词的更多相关文章
- BZOJ4567[Scoi2016]背单词
4567: [Scoi2016]背单词 Time Limit: 10 Sec Memory Limit: 256 MB Submit: 304 Solved: 114 [Submit][Status] ...
- P3294 [SCOI2016]背单词
P3294 [SCOI2016]背单词 Trie+贪心 倒插进树+取出重建+子树处理+贪心遍历 倒插进树:把后缀转化为前缀,所以把字符串倒着插进Trie中 取出重建:重新建立一棵以单词为节点的树,如果 ...
- 4567: [Scoi2016]背单词
4567: [Scoi2016]背单词 https://www.lydsy.com/JudgeOnline/problem.php?id=4567 题意: 题意看了好久,最后在其他人的博客里看懂了的. ...
- 【BZOJ4567】[Scoi2016]背单词 Trie树+贪心
[BZOJ4567][Scoi2016]背单词 Description Lweb 面对如山的英语单词,陷入了深深的沉思,“我怎么样才能快点学完,然后去玩三国杀呢?”.这时候睿智 的凤老师从远处飘来,他 ...
- 【bzoj4567】[Scoi2016]背单词
4567: [Scoi2016]背单词 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1123 Solved: 476[Submit][Status][ ...
- [SCOI2016]背单词——trie树相关
题目描述 Lweb 面对如山的英语单词,陷入了深深的沉思,”我怎么样才能快点学完,然后去玩三国杀呢?“.这时候睿智的凤老师从远处飘来,他送给了 Lweb 一本计划册和一大缸泡椒,他的计划册是长这样的: ...
- [SCOI2016]背单词 题解
背单词 https://www.luogu.com.cn/problem/P3294 前言: Trie树的省选题(瑟瑟发抖QAQ) 问题汇总:(请忽略) (1)对Trie字典树的运用不熟练 (2)没想 ...
- [BZOJ4567][SCOI2016]背单词(Trie+贪心)
1.题意表述十分难以理解,简单说就是:有n个单词,确定一个背的顺序,使总代价最小. 2.因为第(1)种情况的代价是n*n,这个代价比任何一种不出现第(1)种情况的方案都要大,所以最后肯定不会出现“背某 ...
- [SCOI2016]背单词
题目描述 Lweb 面对如山的英语单词,陷入了深深的沉思,”我怎么样才能快点学完,然后去玩三国杀呢?“.这时候睿智的凤老师从远处飘来,他送给了 Lweb 一本计划册和一大缸泡椒,他的计划册是长这样的: ...
- bzoj 4567: [Scoi2016]背单词
Description Lweb 面对如山的英语单词,陷入了深深的沉思,"我怎么样才能快点学完,然后去玩三国杀呢?".这时候睿智 的凤老师从远处飘来,他送给了 Lweb 一本计划册 ...
随机推荐
- 详细分析栈和队列的数据结构的实现过程(Java 实现)
目录 栈和队列的数据结构的实现过程(Java 实现) 栈的数据结构的实现 栈的基础知识回顾 栈的常见应用 基于数组的栈的实现 具体代码设计 基于数组的栈简单的时间复杂度分析 关于栈的一个算法应用:括号 ...
- Elasticsearch7.6 集群部署、集群认证及使用、数据备份
window 环境部署集群 注意:window下载解压elasticsearch一定需要解压多次.例如搭建的3节点的,需要解压3次,防止生成 cluster UUID 一致导致只能看到一个节点 1.e ...
- laravel发送邮件配置
1.设置发送方,即邮件服务器,可以使用163邮箱,设置smtp,开启后获取授权码 2.在env文件配置 MAIL_DRIVER=smtpMAIL_HOST=smtp.163.com //邮箱服务器M ...
- Forward Rendering VS Deferred Rendering
http://gad.qq.com/article/detail/32731 Forward Rendering Deferred Rendering
- 听过N次还是不会之:浏览器输入url后到底经历了什么
有没有这种场景:当你被问起某一项知识点时,你大脑里想起经常看到过这样的问题,可是具体是怎么样就是说不清楚. 好吧,我就是这样的,于是整理一下,实在记不住,以后找起来也方便. 当你在浏览器地址栏里输入一 ...
- 用于测试 JsonAnalyzer2 1.01版的测试用例
14. 原文={"animal":"ca,t","color":"ora:nge","isMale" ...
- .net core Configuration对象
前因:最近在阅读.net core源码,发现关于Configuration介绍的文档都比较多,但是都比较杂乱,(微软文档太官方),所以写下一些自己的感想 主要通过三种使用情况来介绍 Web应用程序使用 ...
- python图片转码为base64
import base64 def image_base64(): with open(image_path, 'rb', )as f: base64_data = base64.b64encode( ...
- java多版本管理
背景 java版本的升级也比较频繁, 每年一个版本或更多 虽然java环境变量的配置无技术性可言, 但对于频繁切换也是比较枯燥的 java版本管理工具 sdkman: https://sdkman.i ...
- Solr专题(二)详解Solr查询参数
一.前言 上节我们讲到了怎样去搭建solr服务,作为全文检索引擎,怎样去使用也是比较关键的.Solr有一套自己的查询方式,所以我们需要另外花时间去学习它的这套模式. 启动solr solr start ...