[bzoj4567][Scoi2016]背单词-Trie+贪心+模型转化
Brief Description
- 给你N个互不相同的字符串,记\(S_i\)为第i个字符串,现在要求你指定N个串的出现顺序,我们用\(V_i\)表示第i个字符串是第几个出现的,则V为1到N的一个排列。我们希望你指定的出现顺序可以使总代价最小
- 一个出现顺序的代价的计算方法如下依次考虑第i个串\(S_i\)对代价的贡献:
- 假如存在一个串\(S_j\), \(S_j\)为\(S_i\)的后缀:
- 假如存在一个串\(S_j\), \(S_j\)为\(S_i\)的后缀,且\(V_j>V_i\)则第i个串对代价的贡献为\(N\times N\)
- 否则,记\(P_i\)为所有满足\(S_j\)为\(S_i\)的后缀的j中\(V_j\)的最大值,第i个串对代价的贡献为\(V_i-P_i\)
- 否则,如果不存在一个串\(S_j\),使得\(S_j\)为\(S_i\)的后缀,则第i个串对代价的贡献为\(V_i\)
- 你需要输出这个最小的总代价.
- 假如存在一个串\(S_j\), \(S_j\)为\(S_i\)的后缀:
Algorithm Design
首先可以证明第一个条件是没有用处的.
然后我们视后缀为一种偏序关系, 那么字符串就构成了一颗树, 那么问题就转化成了给树上每个节点标号使得他的标号减去他的父亲的标号的和最小.
这是一个经典的贪心问题. 我们选择每次都选择最小的size子树进行标号, 不难证明这样做的correctness.
Code
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#define ll long long
#define pa std::pair<int, int>
const int maxn = 100000 + 100;
const int maxlen = 520000 + 100;
int n;
struct edge {
int to, next;
} e[maxn << 1];
char str[maxlen];
int rt = 1, sz = 1, ch[maxlen][26], len, id[maxlen], tot, head[maxn],
size[maxn], f[maxn], cnt, fa[maxn];
std::vector<pa> v[maxn << 1];
inline void ins(int id) {
int p = rt;
for (int i = len; i >= 1; i--) {
int x = str[i] - 'a';
if (!ch[p][x]) {
ch[p][x] = ++sz;
}
p = ch[p][x];
}
::id[p] = id;
}
inline void add_edge(int u, int v) {
e[++tot].to = v;
e[tot].next = head[u];
fa[v] = u;
head[u] = tot;
}
void dfs(int x, int fa) {
if (id[x]) {
add_edge(fa, id[x]);
fa = id[x];
}
for (int i = 0; i < 26; i++) {
if (ch[x][i])
dfs(ch[x][i], fa);
}
}
void dfs2(int x) {
size[x] = 1;
for (int i = head[x]; i; i = e[i].next) {
int y = e[i].to;
dfs2(y);
v[x].push_back(std::make_pair(size[y], y));
size[x] += size[y];
}
std::sort(v[x].begin(), v[x].end());
}
void getf(int x) {
if (x)
f[x] = ++cnt;
for (int i = 0; i < v[x].size(); i++)
getf(v[x][i].second);
}
int main() {
#ifndef ONLINE_JUDGE
freopen("input", "r", stdin);
#endif
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%s", str + 1);
len = strlen(str + 1);
ins(i);
}
dfs(1, 0);
dfs2(0);
getf(0);
ll ans = 0;
for (int i = 1; i <= n; i++)
ans += f[i] - f[fa[i]];
printf("%lld", ans);
}
[bzoj4567][Scoi2016]背单词-Trie+贪心+模型转化的更多相关文章
- [BZOJ4567][SCOI2016]背单词(Trie+贪心)
1.题意表述十分难以理解,简单说就是:有n个单词,确定一个背的顺序,使总代价最小. 2.因为第(1)种情况的代价是n*n,这个代价比任何一种不出现第(1)种情况的方案都要大,所以最后肯定不会出现“背某 ...
- 【BZOJ4567】[Scoi2016]背单词 Trie树+贪心
[BZOJ4567][Scoi2016]背单词 Description Lweb 面对如山的英语单词,陷入了深深的沉思,“我怎么样才能快点学完,然后去玩三国杀呢?”.这时候睿智 的凤老师从远处飘来,他 ...
- BZOJ4567[Scoi2016]背单词
4567: [Scoi2016]背单词 Time Limit: 10 Sec Memory Limit: 256 MB Submit: 304 Solved: 114 [Submit][Status] ...
- [SCOI2016]背单词——trie树相关
题目描述 Lweb 面对如山的英语单词,陷入了深深的沉思,”我怎么样才能快点学完,然后去玩三国杀呢?“.这时候睿智的凤老师从远处飘来,他送给了 Lweb 一本计划册和一大缸泡椒,他的计划册是长这样的: ...
- BZOJ4567 [Scoi2016]背单词 【trie树 + 贪心】
题目链接 BZOJ4567 题解 题意真是鬼畜= = 意思就是说我们应先将一个串的所有后缀都插入之后再插入这个串,产生代价为其到上一个后缀的距离 我们翻转一下串,转化为前缀,就可以建\(trie\)树 ...
- BZOJ4567 SCOI2016背单词(trie+贪心)
倒过来变成查询前缀.考虑怎么排序.第一条代价n*n就相当于inf,说明一个单词的所有前缀都要排在它前面.那么串的依赖关系就是trie的结构.二三条说明代价是Σidi-idfa,那么显然最后的编号应该是 ...
- [bzoj4567][Scoi2016][背单词] (贪心+trie树)
Description Lweb 面对如山的英语单词,陷入了深深的沉思,“我怎么样才能快点学完,然后去玩三国杀呢?”.这时候睿智 的凤老师从远处飘来,他送给了 Lweb 一本计划册和一大缸泡椒,他的计 ...
- 2019.03.25 bzoj4567: [Scoi2016]背单词(trie+贪心)
传送门 题意: 给你n个字符串,不同的排列有不同的代价,代价按照如下方式计算(字符串s的位置为x): 1.排在s后面的字符串有s的后缀,则代价为n^2: 2.排在s前面的字符串有s的后缀,且没有排在s ...
- BZOJ 4567 [SCOI2016]背单词 (Trie树、贪心)
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=4567 题解: 显然答案一定小于\(n\times n\), 字符串倒过来变成前缀建Tr ...
随机推荐
- iOS- UIPickerView餐厅点餐系统
在餐厅里的点餐系统的核心控件就是UIPickerView 今天晚上在整理以前的项目笔记时,特意把UIPickerView单独拿出来,做了一个简陋的点餐道具. 因为没有素材图片,所有大家将就看看吧 0. ...
- C#控件DropDownList下拉列表默认打开
c#中的控件DropDownList要实现默打开确实不容易,之前也是想过页面上的点击之后就打开了,那直接模拟点击不就行了,试过后大失所望,根本没有效果. 于是网上找到了一个例子能实现IE浏览器下的打开 ...
- PowerMock用法[转]
转:http://agiledon.github.io/blog/2013/11/21/play-trick-with-powermock/ 当我们面对一个遗留系统时,常见的问题是没有测试.正如Mic ...
- ubuntu 安装lua错误
转自:http://www.cnblogs.com/softidea/archive/2016/03/02/5236498.html lua.c:80:31: fatal error: readlin ...
- mysql突然无法启动的问题
经常会有这样一个情况是:mysql跑了一段时间后,某一天我们需要重启服务的时候,发现停止后并不能正常启动,会报下面这种错误 这种情况发生的原因绝大多数都是权限的问题: 因为使用了一段时间后,使用期间表 ...
- 【问题解决】Project facet Java version 1.7 (或者1.8)is not supported.
在移植eclipse项目时,如果遇到 “Project facet Java version 1.7 is not supported.” 项目中的jdk1.7不支持.说明项目是其他版本jdk编译的, ...
- 【bzoj4229】选择 离线+LCT
题目描述 现在,我想知道自己是否还有选择. 给定n个点m条边的无向图以及顺序发生的q个事件. 每个事件都属于下面两种之一: 1.删除某一条图上仍存在的边 2.询问是否存在两条边不相交的路径可以从点u出 ...
- Xshell访问本地或者远程Linux虚拟机
背景 在本地PC机上安装了VMware workstation和Ubuntu系统,但是每次访问虚拟机都需要输入登陆密码,比较不方便.为此,通过Xshell来访问虚拟机,提高工作效率. 步骤 1.打开虚 ...
- 配置bond和vlan
网卡是光口还是电口的方法ethtool 网卡名字 一看速度二看port是否是firber首先查看需要做bond的物理网卡,如enp130s0f0,enp131s0f0以物理网卡为enp130s0f0, ...
- html的head内标签
ctrl+?:自动注释 ctrl+/: 注释多行,再按一次,取消注释的多行. 一,*********本地测试的方法:1-找到文件路径,直接浏览器打开:2-pycharm打开测试. 二,模板的解释: ...