1.题意表述十分难以理解,简单说就是:有n个单词,确定一个背的顺序,使总代价最小。

2.因为第(1)种情况的代价是n*n,这个代价比任何一种不出现第(1)种情况的方案都要大,所以最后肯定不会出现“背某个单词的时候它的后缀还没背”的情况。

3.考虑将每个串和单词表中它的最长后缀连边,则形成了一棵树。我们需要给树上每个点分配一个1~n的整数v[]且两两不同(就是背的顺序,要保证儿子分配到的数一定大于父亲)。那么总代价就是所有点的v[i]-v[fa[i]]。可以发现,要让总代价最小,最终的涂色序列(就是背的顺序)是这棵树的一个DFS序。

4.关于建树,将所有串翻转变成前缀问题,再对所有串建Trie即可。

5.考虑哪个DFS序能让总代价最小,考虑一个点的所有儿子,当走入一个儿子时,其它儿子和父亲的差就会+1,其余点不变。那么要让答案最小就必须要尽快从那个儿子中出来,于是肯定是选择size最小的那个儿子。

这个结论全网都说十分显然但我既想不到也不会证,感觉自己贪心水平十分低下。

 #include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
#define For(i,x) for (int i=h[x],k; i; i=nxt[i])
typedef long long ll;
using namespace std; const int N=;
int n,tim,nd=,cnt,tot,top,h[N],to[N],nxt[N<<];
int id[N],fa[N],ch[N][],stk[N],a[N],sz[N],v[N];
ll ans;
char s[N];
vector<int>ve[N]; void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; }
bool cmp(int a,int b){ return sz[a]<sz[b]; } void ins(int k,char s[]){
int x=,len=strlen(s+);
for (int i=len; i; i--){
if (!ch[x][s[i]-'a']) ch[x][s[i]-'a']=++nd;
x=ch[x][s[i]-'a'];
}
v[x]=k;
} void dfs1(int x){
if (v[x]) fa[v[x]]=stk[top],add(stk[top],v[x]),stk[++top]=v[x];
rep(i,,) if (ch[x][i]) dfs1(ch[x][i]);
if (v[x]) top--;
} void dfs2(int x){ sz[x]=; For(i,x) if ((k=to[i])!=fa[x]) dfs2(k),sz[x]+=sz[k]; } void dfs3(int x){
tot=; id[x]=++tim;
For(i,x) if ((k=to[i])!=fa[x]) ve[x].push_back(k);
sort(ve[x].begin(),ve[x].end(),cmp); int ed=ve[x].size()-;
rep(i,,ed) dfs3(ve[x][i]);
} int main(){
freopen("bzoj4567.in","r",stdin);
freopen("bzoj4567.out","w",stdout);
scanf("%d",&n);
rep(i,,n) scanf("%s",s+),ins(i,s);
dfs1(); dfs2(); dfs3();
rep(i,,n) ans+=id[i]-id[fa[i]];
printf("%lld\n",ans);
return ;
}

[BZOJ4567][SCOI2016]背单词(Trie+贪心)的更多相关文章

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

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

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

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

  3. BZOJ4567[Scoi2016]背单词

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

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

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

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

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

  6. BZOJ4567 SCOI2016背单词(trie+贪心)

    倒过来变成查询前缀.考虑怎么排序.第一条代价n*n就相当于inf,说明一个单词的所有前缀都要排在它前面.那么串的依赖关系就是trie的结构.二三条说明代价是Σidi-idfa,那么显然最后的编号应该是 ...

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

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

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

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

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

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

随机推荐

  1. [译] 用HTML5捕获音频和视频

    原文地址:http://www.html5rocks.com/en/tutorials/getusermedia/intro/ 概述 有了HTML5,我们就可以在不借助Flash或者Silverlig ...

  2. 解决多个python的兼容问题

    方法1:将(安装路径和scripts)路径添加到系统环境变量,谁的顺序在前面谁就是默认的 方法2:修改python的名字,然后再终端输入比如python2或者python3

  3. 【逆向知识】开发WinDBG扩展DLL

    如何开发WinDbg扩展DLL WinDbg扩展DLL是一组导出的回调函数,用于实现用户定义的命令.以便从内存转储中提取特定的信息.扩展dll由调试器引擎加载,可以在执行用户模式或内核模式调试时提供自 ...

  4. Task多线程进行多进程

    using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using Sys ...

  5. SSD固态硬盘检测工具AS SSD参数

    一. 使用AS SSD Benchmark进行查看 包括了4个方面的测试(顺序读写.4K随机读写.64线程4K读写.寻道时间) AS SSD的主要测试,也是网上最常见得到测试成绩的,是它主界面上持续. ...

  6. 09 Command Documentation 命令文档

    Command Documentation 命令文档   There is a suite of programs to build and process Go source code. Inste ...

  7. Scrapy:创建爬虫程序的方式

    Windows 10家庭中文版,Python 3.6.4,Scrapy 1.5.0, 在Scrapy中,建立爬虫程序或项目的方式有两种(在孤读过Scrapy的大部分文档后): 1.继承官方Spider ...

  8. Python_oldboy_自动化运维之路_全栈考试(七)

    1. 计算100-300之间所有能被3和7整除的所有数之和 # -*- coding: UTF-8 -*- #blog:http://www.cnblogs.com/linux-chenyang/ c ...

  9. HDU 4632 Palindrome subsequence(区间DP求回文子序列数)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4632 题目大意:给你若干个字符串,回答每个字符串有多少个回文子序列(可以不连续的子串).解题思路: 设 ...

  10. 解决insert语句插入时,需要写列值的问题

    今天发现解决这个问题其实很简单,闲话不多谈,我直接附上语句 ) select @s = isnull(@s+',', '') + [name] from syscolumns where id = o ...