这是一道贪心题

刚开始yy出来一个比较\(sb\)的贪心

之后发现它错了

首先这道题得先把题面翻译成人话

  1. 如果存在一个单词是它的后缀,且当前没被填入,代价为\(n*n\);

  2. 如果不存在一个单词是它的后缀,代价为\(x\);

  3. 如果存在一个单词是它的后缀,且已填入的是它后缀的单词中序号最大的为\(y\),代价为\(x-y\)。

显然如果出现了第一种情况那肯定就凉了,这个花费太大了

显然这是可以避免的,我们在插入一个串之前就必须把它的所有后缀插入

所以这里就需要\(Trie\)树了,我们将所有的串倒着插入\(Trie\)树,之后\(Trie\)树就可以处理后缀了

那之后呢,我们在原来的\(Trie\)上贪心吗

不是的,我们应该在建立一个新图,在这个图上我们用一个点代表一个字符串,每个点的父亲是他的后缀

于是我们就得到了一棵新的树

之后贪心就好了,优先选择子树较小的

这是非常显然的

首先我们明确一点,就是一个子树内部的相对答案是不会变的,就是说在这个子树内部被选择的第一个点被选择的顺序是\(x\),那么答案一定会是\(x+val\),\(val\)是固定的一个数,也就是这个子树内部的最优策略

所以我们要尽量保证进入每一棵子树的\(x\)的和尽量的小,显然我们优先选择较小的可以做到这一点

代码

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<bitset>
#define re register
#define mp std::make_pair
#define maxn 510005
struct E
{
int v,nxt;
}e[maxn<<1];
char S[maxn];
int n,cnt,tot;
long long ans;
std::bitset<maxn> f;
int son[maxn][26];
int sz[maxn];
int num,head[maxn],sum[maxn];
typedef std::pair<int,int> pii;
std::priority_queue<pii,std::vector<pii>,std::greater<pii> > q[maxn];
inline void add_edge(int x,int y)
{
e[++num].v=y;
e[num].nxt=head[x];
head[x]=num;
}
inline void ins()
{
scanf("%s",S+1);
int now=0;
int len=strlen(S+1);
for(re int i=len;i;--i)
{
if(!son[now][S[i]-'a']) son[now][S[i]-'a']=++cnt;
now=son[now][S[i]-'a'];
}
f[now]=1;
}
void build(int x,int pre)
{
for(re int i=0;i<26;i++)
if(son[x][i])
{
if(f[son[x][i]]) add_edge(pre,son[x][i]),build(son[x][i],son[x][i]);
else build(son[x][i],pre);
}
}
void dfs(int x)
{
sum[x]=1;
for(re int i=head[x];i;i=e[i].nxt)
{
dfs(e[i].v);
sum[x]+=sum[e[i].v];
q[x].push(mp(sum[e[i].v],e[i].v));
}
}
void last(int x,int pre)
{
while(!q[x].empty())
{
tot++;
ans+=tot-pre;
int mid=q[x].top().second;
last(mid,tot);
q[x].pop();
}
}
int main()
{
scanf("%d",&n);
for(re int i=1;i<=n;i++) ins();
build(0,0);
dfs(0);
last(0,0);
std::cout<<ans;
return 0;
}

【[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. [SCOI2016]背单词

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

  10. bzoj 4567: [Scoi2016]背单词

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

随机推荐

  1. nodejs设置服务端允许跨域

    //设置跨域访问 app.all('*', function(req, res, next) { res.header("Access-Control-Allow-Origin", ...

  2. ASP.Net 之委托事件

    1.首先给一张图让大家了解什么是委托?它的优缺点是什么? 2.通过代码的运用更深入地了解委托事件(窗体应用程序) 1)下面我们先定义一个无参数的委托. //1.0 定义一个自定义的委托,此委托的签名是 ...

  3. Hadoop学习笔记(9) ——源码初窥

    Hadoop学习笔记(9) ——源码初窥 之前我们把Hadoop算是入了门,下载的源码,写了HelloWorld,简要分析了其编程要点,然后也编了个较复杂的示例.接下来其实就有两条路可走了,一条是继续 ...

  4. SqlServer示例数据库Northwind(一)——实体关系

    在学习Spss统计分析.EA画实体关系图.PowerDesigner画数据库模型图等时,苦于找不到一个好的实例.由于实际工作中项目使用的表结构属于公司的商业保密内容,且在和大家交流时,其结构大家也不熟 ...

  5. C#学习笔记-外观模式

    题目:股民买卖股票 实现: static void Main(string[] args) { Stock1 gu1 = new Stock1(); Stock2 gu2 = new Stock2() ...

  6. python学习之老男孩python全栈第九期_day023知识点总结——类和对象命名空间、组合

    一. 类和对象命名空间类里 可以定义两种属性: 1. 静态属性 2. 动态属性 class Course: language = 'Chinese' def __init__(self, teache ...

  7. Vue打包桌面程序

    开源的地址:https://github.com/electron/electron-quick-start 一.运行 1. 安装依赖 cnpm install electron --save cnp ...

  8. 【vue入门】日志demo,增删改查的练习(无vuex版本)

    安装 1. 确定电脑已装node和npm 出现版本号则说明电脑已经安装好node和npm2. 创建一个基于webpack的项目   3. 在项目里安装依赖 4. 运行 配置路由为了动态渲染各个页面的组 ...

  9. Android学习笔记(4)----Rendering Problems(The graphics preview in the layout editor may not be accurate)

    在Android Studio中新建了一个 setting.xml 文件,布局好文件后,从 Text 界面切换到 Design 界面,显示了如下错误: 网上搜寻 The graphics previe ...

  10. 仿小米便签图文混排 EditText解决尾部插入文字bug

    一直想实现像小米便签那样的图文混排效果,收集网上的办法无非三种: 1.自定义布局,每张图片是一个ImageView,插入图片后插入EditText,缺点是实现复杂,不能像小米便签那样同时选中图片和文字 ...