题目描述

Lweb 面对如山的英语单词,陷入了深深的沉思,”我怎么样才能快点学完,然后去玩三国杀呢?“。这时候睿智的凤老师从远处飘来,他送给了 Lweb 一本计划册和一大缸泡椒,他的计划册是长这样的:

—————序号 单词—————

1 2......n-2n-1 n—————

然后凤老师告诉 Lweb ,我知道你要学习的单词总共有 n 个,现在我们从上往下完成计划表,对于一个序号为 x 的单词(序号 1...x-1 都已经被填入):

1) 如果存在一个单词是它的后缀,并且当前没有被填入表内,那他需要吃 n*n 颗泡椒才能学会;

2) 当它的所有后缀都被填入表内的情况下,如果在 1...x-1 的位置上的单词都不是它的后缀,那么你吃 x 颗泡椒就能记住它;

3) 当它的所有后缀都被填入表内的情况下,如果 1...x-1的位置上存在是它后缀的单词,所有是它后缀的单词中,序号最大为 y ,那么你只要吃 x-y 颗泡椒就能把它记住。

Lweb 是一个吃到辣辣的东西会暴走的奇怪小朋友,所以请你帮助 Lweb ,寻找一种最优的填写单词方案,使得他记住这 n 个单词的情况下,吃最少的泡椒。

输入输出格式

输入格式:

输入一个整数 n ,表示 Lweb 要学习的单词数。接下来 n 行,每行有一个单词(由小写字母构成,且保证任意单词两两互不相同)1<=n<=100000, 所有字符的长度总和 1<=|len|<=510000

输出格式:

Lweb 吃的最少泡椒数

输入输出样例

输入样例#1:

2
a
ba
输出样例#1:

2

我们将“后缀”转化为“前缀”,那么很显然这是一个可以在$Trie$树上解决的问题。

我们建完$Trie$树后,我们建立一个根节点$0$,发现其实答案就是所有节点的编号与其父亲节点的编号差值和。

这个结论是建立在$1$号情况不能出现的情况下,因为$1$号情况代价最大,我们显然必须避开,并且一定能够避开。

那么现在问题就变成了给你一棵树,让你给节点编号(父节点编号一定比子节点小),求所有节点的编号与其父亲节点的编号差值和最小值。

很容易得到的一个贪心策略是:每次选深度最小的子树先标号。

简要证明一下:因为对于一个子树,其内部最优值一定是不变的,影响答案的只有与当前节点相邻节点的编号关系。那么我们一定先选子树$size$小的先编号,一定能得到最优值。

那么$dfs$的时候我们要选最小的$size$,如何实现?我们可以开个栈来按顺序存储要访问的节点,就可以了。

菜鸡附上转载地址:http://www.cnblogs.com/NaVi-Awson/p/7648048.html

%%%%SAC

 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<stack>
using namespace std;
typedef long long ll;
const int M=;
const int N=;
struct Node
{
int next,to;
}edge[N+];
ll ans;
int vis[N+],n;
char s[M+];
int trie[M+][],pd[M+],pos,num,head[N+],size[N+],tot,tmp[N+];
stack<int>S;
void add(int u,int v)
{
num++;
edge[num].next=head[u];
head[u]=num;
edge[num].to=v;
}
void insert(char *s,int len,int id)
{int i;
int x=;
for (i=len-;i>=;i--)
{
if (!trie[x][s[i]-'a']) trie[x][s[i]-'a']=++pos;
x=trie[x][s[i]-'a'];
}
pd[x]=id;
}
void dfs(int x,int last)
{int i;
if (pd[x]) add(last,pd[x]),last=pd[x];
for (i=;i<;i++)
if (trie[x][i])
dfs(trie[x][i],last);
}
void get_size(int x)
{int i;
size[x]=;
for (i=head[x];i;i=edge[i].next)
{
int v=edge[i].to;
get_size(v);
size[x]+=size[v];
}
}
bool cmp(int x,int y)
{
return size[x]<size[y];
}
void get_ans(int x,int fa)
{int i;
int top=;
vis[x]=++tot;
ans+=vis[x]-vis[fa];
for (i=head[x];i;i=edge[i].next)
{
int v=edge[i].to;
tmp[++top]=v;
}
sort(tmp+,tmp+top+,cmp);
for (i=top;i>=;i--)
S.push(tmp[i]);
while (top--)
{
i=S.top();
S.pop();
get_ans(i,x);
}
}
int main()
{int i;
cin>>n;
for (i=;i<=n;i++)
{
scanf("%s",s);
insert(s,strlen(s),i);
}
dfs(,);
get_size();
get_ans(,);
cout<<ans;
}

[SCOI2016]背单词的更多相关文章

  1. BZOJ4567[Scoi2016]背单词

    4567: [Scoi2016]背单词 Time Limit: 10 Sec Memory Limit: 256 MB Submit: 304 Solved: 114 [Submit][Status] ...

  2. P3294 [SCOI2016]背单词

    P3294 [SCOI2016]背单词 Trie+贪心 倒插进树+取出重建+子树处理+贪心遍历 倒插进树:把后缀转化为前缀,所以把字符串倒着插进Trie中 取出重建:重新建立一棵以单词为节点的树,如果 ...

  3. 4567: [Scoi2016]背单词

    4567: [Scoi2016]背单词 https://www.lydsy.com/JudgeOnline/problem.php?id=4567 题意: 题意看了好久,最后在其他人的博客里看懂了的. ...

  4. 【BZOJ4567】[Scoi2016]背单词 Trie树+贪心

    [BZOJ4567][Scoi2016]背单词 Description Lweb 面对如山的英语单词,陷入了深深的沉思,“我怎么样才能快点学完,然后去玩三国杀呢?”.这时候睿智 的凤老师从远处飘来,他 ...

  5. 【bzoj4567】[Scoi2016]背单词

    4567: [Scoi2016]背单词 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1123 Solved: 476[Submit][Status][ ...

  6. [SCOI2016]背单词——trie树相关

    题目描述 Lweb 面对如山的英语单词,陷入了深深的沉思,”我怎么样才能快点学完,然后去玩三国杀呢?“.这时候睿智的凤老师从远处飘来,他送给了 Lweb 一本计划册和一大缸泡椒,他的计划册是长这样的: ...

  7. [SCOI2016]背单词 题解

    背单词 https://www.luogu.com.cn/problem/P3294 前言: Trie树的省选题(瑟瑟发抖QAQ) 问题汇总:(请忽略) (1)对Trie字典树的运用不熟练 (2)没想 ...

  8. [BZOJ4567][SCOI2016]背单词(Trie+贪心)

    1.题意表述十分难以理解,简单说就是:有n个单词,确定一个背的顺序,使总代价最小. 2.因为第(1)种情况的代价是n*n,这个代价比任何一种不出现第(1)种情况的方案都要大,所以最后肯定不会出现“背某 ...

  9. bzoj 4567: [Scoi2016]背单词

    Description Lweb 面对如山的英语单词,陷入了深深的沉思,"我怎么样才能快点学完,然后去玩三国杀呢?".这时候睿智 的凤老师从远处飘来,他送给了 Lweb 一本计划册 ...

随机推荐

  1. C语言第三次博客作业—循环结构

    一.PTA实验作业 题目1 1.实验代码 int N,i; //N为用户数 char sex; //sex表示性别 double High; //Hight表示身高 scanf("%d&qu ...

  2. C语言博客作业--函数

    一.PTA实验作业 题目1 (6-7) (1).本题PTA提交列表 (2)设计思路 设计第一个函数判断是否完数int factorsum( int number ) 定义sum.i:sum初始化归0, ...

  3. C语言二维数组作业

    一.PTA实验作业 题目1:7-3 出生年 1. 本题PTA提交列表 2. 设计思路 1.声明一个函数different()用来计算一个年份的不同数字个数 2.定义y(y是来计算符合要求的年份的量), ...

  4. 201621123068 Week04-面向对象设计与继承

    1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 答:继承.多态.重载.关键字.父类与子类 1.2 尝试使用思维导图将这些关键词组织起来. 2. 书面作业 1. 面向对象设计(大 ...

  5. ios swift例子源码网址总结

    http://blog.csdn.net/woaifen3344/article/details/40079351 http://www.ruanman.net/swift/learn/4607.ht ...

  6. Binary Tree Xorder Traversal

     * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeN ...

  7. js定时刷新页面.

    //页面定时刷新.2017.09.27 $(document).ready(function () { self.setInterval(function () { var d = new Date( ...

  8. dede使用心得

    Question one: 最近做了一些视频教程传到优酷网站上,但我想引入这些视频教程到我的网站,在发表时我发现织梦CMS自带的编辑器又不直接支持优酷等视频网站的引用.所以为了方便教程的发布,特意在网 ...

  9. 关于win10系统1709版本安装JDK出现变量配置正确但仍有“java不是内部或外部命令”的解决办法

    背景:联想拯救者R720笔记本,系统一键还原了,需要重新安装一部分软件,最基本的就是JDK,但今天在安装时遇到了问题,之前安装的1.8版本,没有仔细配置环境变量,这一次安装的是1.7版本的,仔仔细细配 ...

  10. iot会议纪要 20180105

    1.需求概述设备 <-->物接入 <--> 云端认证授权协议解析主题 端点endpoint(地址)->设备thing(用户)->身份principal(密码)-&g ...