[bzoj4567][Scoi2016][背单词] (贪心+trie树)
Description
Input
Output
Lweb 吃的最少泡椒数
Sample Input
a
ba
Sample Output
Solution
可以利用后缀的性质将所有字符串反过来建字典树
那么求最优填词方案也就是求代价最小的访问序,即一个最优的dfs序,这样就可以去掉第一种吃泡椒的方案,因为代价太大
可以证明,优先访问单词数量小的子树更优,满足贪心性质
这样就解出了此题
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define MaxN 100010
#define MaxL 500010
namespace io{
#define MaxBuf 1<<22
#define Blue() ((S==T&&(T=(S=B)+fread(B,1,MaxBuf,stdin),S==T))?0:*S++)
char B[MaxBuf],*S=B,*T=B;
template<class Type>inline void Rin(Type &x){
x=;int c=Blue();
for(;c<||c>;c=Blue())
;
for(;c>&&c<;c=Blue())
x=(x<<)+(x<<)+c-;
}
inline void geTc(char *C,int &x){
x=;char c=Blue();
for(;c<'a'||c>'z';c=Blue())
;
for(;c>='a'&&c<='z';c=Blue())
*C++=c,x++;
}
}
int n;
char s[MaxL];
long long ans(0LL);
class Trie{
public:
int ch[MaxL][],tot;
bool val[MaxL];
Trie(){
tot=;
memset(ch,,sizeof ch);
memset(val,false,sizeof val);
}
inline void insert(char *C,int len){
int now=;
for(int i=len-;~i;i--){
if(!ch[now][C[i]-'a'])
ch[now][C[i]-'a']=++tot;
now=ch[now][C[i]-'a'];
}
val[now]=true;
}
}T;
namespace DFS{
int sz[MaxN],q[MaxN],top;
struct Pointer{
int to;
Pointer *next;
}*fir[MaxN];
inline void link(int x,int y){
static Pointer mem[MaxN],*tot=mem;
*++tot=(Pointer){y,fir[x]},fir[x]=tot;
}
void _dfs(int at,int fa){
static int timer=;
if(T.val[at]){
link(fa,++timer);
sz[fa=timer]=;
}
for(int i=;i<;i++)
if(T.ch[at][i])
_dfs(T.ch[at][i],fa);
}
void maintain(int at){
for(Pointer *iter=fir[at];iter;iter=iter->next){
maintain(iter->to);
sz[at]+=sz[iter->to];
}
}
bool cmp(int x,int y){
return sz[x]<sz[y];
}
void calc(int at,int pre){
static int timer;
timer++;
ans+=timer-pre;
pre=timer;
int l=top+,r=top;
for(Pointer *iter=fir[at];iter;iter=iter->next)
q[++r]=iter->to;
std::sort(q+l,q++r,cmp);
top=r;
for(int i=l;i<=r;i++)
calc(q[i],pre);
top=l-;
}
}
int main(){
io::Rin(n);
for(int i=,len;i<=n;i++){
io::geTc(s,len);
T.insert(s,len);
}
DFS::_dfs(,);
DFS::maintain();
DFS::calc(,);
printf("%lld\n",ans);
return ;
}
[bzoj4567][Scoi2016][背单词] (贪心+trie树)的更多相关文章
- BZOJ4567 [Scoi2016]背单词 【trie树 + 贪心】
题目链接 BZOJ4567 题解 题意真是鬼畜= = 意思就是说我们应先将一个串的所有后缀都插入之后再插入这个串,产生代价为其到上一个后缀的距离 我们翻转一下串,转化为前缀,就可以建\(trie\)树 ...
- 2019.03.25 bzoj4567: [Scoi2016]背单词(trie+贪心)
传送门 题意: 给你n个字符串,不同的排列有不同的代价,代价按照如下方式计算(字符串s的位置为x): 1.排在s后面的字符串有s的后缀,则代价为n^2: 2.排在s前面的字符串有s的后缀,且没有排在s ...
- BZOJ4567 SCOI2016背单词(trie+贪心)
倒过来变成查询前缀.考虑怎么排序.第一条代价n*n就相当于inf,说明一个单词的所有前缀都要排在它前面.那么串的依赖关系就是trie的结构.二三条说明代价是Σidi-idfa,那么显然最后的编号应该是 ...
- [SCOI2016] 背单词 (Trie树)
$pdf\space solution$ link #include<iostream> #include<algorithm> #include<cstrin ...
- BZOJ4567[Scoi2016]背单词
4567: [Scoi2016]背单词 Time Limit: 10 Sec Memory Limit: 256 MB Submit: 304 Solved: 114 [Submit][Status] ...
- [BZOJ4567][SCOI2016]背单词(Trie+贪心)
1.题意表述十分难以理解,简单说就是:有n个单词,确定一个背的顺序,使总代价最小. 2.因为第(1)种情况的代价是n*n,这个代价比任何一种不出现第(1)种情况的方案都要大,所以最后肯定不会出现“背某 ...
- [bzoj4567][Scoi2016]背单词-Trie+贪心+模型转化
Brief Description 给你N个互不相同的字符串,记\(S_i\)为第i个字符串,现在要求你指定N个串的出现顺序,我们用\(V_i\)表示第i个字符串是第几个出现的,则V为1到N的一个排列 ...
- [Scoi2016]背单词(trie+贪心)
题意:重新解释一下题意吧(题意晦涩难懂) 给定n个单词,你可以按照顺序学习,当学习这一单词时,这个单词是第x个要学习的单词,需要的代价分三类: 1.若存在其他单词是其后缀没被学习,则代价为n2 2.若 ...
- 【BZOJ4567】[Scoi2016]背单词 Trie树+贪心
[BZOJ4567][Scoi2016]背单词 Description Lweb 面对如山的英语单词,陷入了深深的沉思,“我怎么样才能快点学完,然后去玩三国杀呢?”.这时候睿智 的凤老师从远处飘来,他 ...
随机推荐
- Java应用程序中的声音播放
声音可以创造意境,触发遐想,当与虚拟图像相结合时,更加可以让整个世界充满幻觉,声音是多媒体技术的基础. 播放声音是Java对多媒体的支持一个重要部分,它支持的声音文件类型主要有: AU - (扩展名为 ...
- 在WIN7里IE8的开发人员工具打不开的解决办法
IE8新增了开发人员工具,非常不错,比早期的DevToolbar好用多了.不过在我的Win7下使用的时候偶尔会出现一个莫名其妙的问题,就是整个开发人员工具窗口消失了,打不开了.当你使用win+Tab切 ...
- 继续不温不火Windows Phone
已经辞了,人也离开帝都了.是否还会回去? 不知道,也许脑子突然正常了又跑回去了. 如题,继续不温不火的Windows Phone. 今年2014,没错,Windows Phone是新加了好几家厂商,微 ...
- bzoj 1579: [Usaco2009 Feb]Revamping Trails 道路升级【分层图+spfa】
至死不用dijskstra系列2333,洛谷上T了一个点,开了O2才过 基本想法是建立分层图,就是建k+1层原图,然后相邻两层之间把原图的边在上一层的起点与下一层的终点连起来,边权为0,表示免了这条边 ...
- 10.27night清北刷题班
/* 枚举每个部分的总和,利用前缀和进行检验. 如果能分成4部分就一定能分成2部分,就筛了一边素数优化.清空数组!!! */ #include<bits/stdc++.h> #define ...
- [Swift通天遁地]一、超级工具-(18)创建强大、灵活的日期时间拾取器
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- Nginx开启http2访问和gzip网页压缩功能
准备工作 如果Nginx要开启http2需要满足以下2个条件: nginx >=1.9.5 openSSL >= 1.0.2 所以这里我们首先要检查Nginx的版本如果没有安装要先安装 ...
- c++ memset函数
函数名称:memset 函数所需头文件:#include<cstring> 函数作用:内存赋值函数,用来给某一块内存空间进行赋值的. 函数结构:memset(变量,一个数字,一个数字) ...
- Docker (1) 基本概念和安装
Docker简介 什么是容器? 一种虚拟化的方案,操作系统级别的虚拟化.容器是一个轻量的.独立的.可执行的包,包含了执行它所需要的所有东西:代码.运行环境.系统工具.系统库.设置.很长一段时间中,容器 ...
- MVC学习-发送请求
在HomeControl中添加一个Action,代码如下: public ActionResult Add() { return View(); } 当View()中不写任何参数时,默认会调用同名的视 ...