【BZOJ4567】[Scoi2016]背单词

Description

Lweb 面对如山的英语单词,陷入了深深的沉思,“我怎么样才能快点学完,然后去玩三国杀呢?”。这时候睿智
的凤老师从远处飘来,他送给了 Lweb 一本计划册和一大缸泡椒,他的计划册是长这样的:
—————
序号  单词
—————
 1
 2
……
n-2
n-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 个单词的情况下,吃最少的泡椒。

Input

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

Output

Lweb 吃的最少泡椒数

Sample Input

2
a
ba

Sample Output

2

题解:我们将单词倒序扔到Trie树中去,然后根据贪心可知如果想填入一个单词,那么它父亲节点上的单词一定已经被填入,现在的问题就是我们如何处理一个父亲的多个儿子的填入顺序。

又根据贪心可知,如果一个单词有多个儿子,那么一定先走子树最小的那个儿子,这是可证明的,但我懒啊~

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
int n,tot,cnt,now;
long long ans;
const int maxn=100010;
struct node
{
int ch[26],v,sm,from;
}p[500010];
char str[500010];
int fa[maxn],next[maxn],head[maxn],to[maxn],pos[maxn],q[maxn],siz[maxn],s[maxn],Q[maxn];
void add(int a,int b)
{
to[cnt]=b,next[cnt]=head[a],head[a]=cnt++;
}
void dfs1(int x)
{
siz[x]=1;
for(int i=head[x];i!=-1;i=next[i]) dfs1(to[i]),siz[x]+=siz[to[i]];
}
bool cmp(int a,int b)
{
return siz[a]<siz[b];
}
void dfs2(int x)
{
int i,sum=0;
ans+=s[x]-s[fa[x]];
for(i=head[x];i!=-1;i=next[i]) q[++sum]=to[i];
sort(q+1,q+sum+1,cmp);
for(sum=0,i=head[x];i!=-1;i=next[i]) to[i]=q[++sum];
for(i=head[x];i!=-1;i=next[i]) s[to[i]]=++now,dfs2(to[i]);
}
int main()
{
scanf("%d",&n);
int i,j,a,b,u;
tot=1;
for(i=1;i<=n;i++)
{
scanf("%s",str);
a=strlen(str);
for(u=1,j=a-1;j>=0;j--)
{
b=str[j]-'a';
if(!p[u].ch[b]) p[u].ch[b]=++tot,p[p[u].ch[b]].from=u;
u=p[u].ch[b];
}
p[u].v=i,pos[i]=u;;
}
memset(head,-1,sizeof(head));
for(i=1;i<=n;i++)
{
u=p[pos[i]].from;
while(u!=1&&!p[u].v) u=p[u].from;
fa[i]=p[u].v,add(fa[i],i);
}
dfs1(0),dfs2(0);
printf("%lld",ans);
return 0;
}

【BZOJ4567】[Scoi2016]背单词 Trie树+贪心的更多相关文章

  1. [SCOI2016] 背单词 (Trie 树,贪心)

    题目链接 大致题意 给你 \(n\) 个字符串, 要求你给出最小的代价. 对于每个字符串: 1.如果它的后缀在它之后,那么代价为 \(n^2\). 2.如果一个字符串没有后缀,那么代价为 \(x\), ...

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

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

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

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

  4. [bzoj4567][Scoi2016]背单词-Trie+贪心+模型转化

    Brief Description 给你N个互不相同的字符串,记\(S_i\)为第i个字符串,现在要求你指定N个串的出现顺序,我们用\(V_i\)表示第i个字符串是第几个出现的,则V为1到N的一个排列 ...

  5. BZOJ 4567 [SCOI2016]背单词 (Trie树、贪心)

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=4567 题解: 显然答案一定小于\(n\times n\), 字符串倒过来变成前缀建Tr ...

  6. BZOJ4567[Scoi2016]背单词

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

  7. BZOJ4567 [Scoi2016]背单词 【trie树 + 贪心】

    题目链接 BZOJ4567 题解 题意真是鬼畜= = 意思就是说我们应先将一个串的所有后缀都插入之后再插入这个串,产生代价为其到上一个后缀的距离 我们翻转一下串,转化为前缀,就可以建\(trie\)树 ...

  8. [bzoj4567][Scoi2016][背单词] (贪心+trie树)

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

  9. 2019.03.25 bzoj4567: [Scoi2016]背单词(trie+贪心)

    传送门 题意: 给你n个字符串,不同的排列有不同的代价,代价按照如下方式计算(字符串s的位置为x): 1.排在s后面的字符串有s的后缀,则代价为n^2: 2.排在s前面的字符串有s的后缀,且没有排在s ...

随机推荐

  1. Asp.Net MVC之防止用户注入脚本参数

    假设有一个Controller,代码如下: public string Browse(string genre) { string message = "Store.Browse, Genr ...

  2. python selenium --滚动条处理

    转自:http://www.cnblogs.com/fnng/p/3256563.html 本节重点: 控制滚动条到底部 有时候我们需要控制页面滚动条上的滚动条,但滚动条并非页面上的元素,这个时候就需 ...

  3. sklearn 随机森林方法

    Notes The default values for the parameters controlling the size of the trees (e.g. max_depth, min_s ...

  4. Scrapy使用问题整理(转载)

    转载自:http://blog.csdn.net/heu07111121/article/details/50832999   最近尝试使用Scrapy进行数据抓取,并尝试在windows7 64位系 ...

  5. .Net程序员面试 每个人都应知道篇 (回答Scott Hanselman的问题)

    昨天回答了Scott Hanselman在他清单上关于C#那部分的题目,.Net 程序员面试 C# 语言篇 (回答Scott Hanselman的问题),今天接着回答他在清单上列出的"每个写 ...

  6. atitit.http get post的原理以及框架实现java php

    atitit.http get post的原理以及框架实现java php 1. 相关的设置 1 1.1. urlencode 1 1.2. 输出流的编码 1 1.3. 图片,文件的post 1 2. ...

  7. C#将URL中的参数转换成字典Dictionary<string, string>

    /// <summary> /// 将获取的formData存入字典数组 /// </summary> public static Dictionary<String, ...

  8. cacheManager载入问题

    net.sf.ehcache.CacheException: Another unnamed CacheManager already exists in the same VM. Please pr ...

  9. CentOS上扩充lv-root空间步骤详解

    查看服务器发现vg_host01-lv_root下的空间占用的比较多,需要扩容. 有以下两种方案: )利用空余的磁盘,扩展lv_root的大小(推荐) )将lv_home的空间挪出一部分给lv_roo ...

  10. hdu 1213 (How Many Tables)(简单的并查集,纯模板)

    How Many Tables Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...