[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 ...
随机推荐
- OSG学习:多重纹理映射
#include<osgViewer\Viewer> #include<osg\Node> #include<osg\Geode> #include<osg\ ...
- HDU 1995 R-汉诺塔V
https://vjudge.net/contest/67836#problem/R 用1,2,...,n表示n个盘子,称为1号盘,2号盘,....号数大盘子就大.经典的汉诺塔问 题经常作为一个递归的 ...
- mysql 时区问题:The server time zone value '???ú±ê×??±??' is unrecognized
org.apache.ibatis.exceptions.PersistenceException: ### Error querying database. Cause: java.sql.SQLE ...
- Windows Server 2012四大版本介绍
今天刚好要尝试安装Windows Server 2012,在网上百度了下发现有4个版本,分别是: Datacenter数据中心版. Standard标准版. Essentials版. Foundati ...
- cmake & make
大家都知道,写程序大体步骤为: 1.用编辑器编写源代码,如.c文件. 2.用编译器编译代码生成目标文件,如.o. 3.用链接器连接目标代码生成可执行文件,如.exe. 但如果源文件太多,一个一个编译时 ...
- tomcat执行shutdown.sh进程残留的解决办法
我们执行shutdown.sh指令的时候有时会发现进程并没有被关掉而是越来越多,这种情况一般是项目造成的,具体原因未去调查.由于tomcat自己有相应的保护机制,所以我们只需要强制结束其进程即可,下面 ...
- (六)Redis有序集合Sorted set操作
Sorted set全部命令如下: zadd key score1 member1 score2 member2 ... # 将一个或多个member元素及其score值加入到有序集合key当中 z ...
- BZOJ4827:[AH2017/HNOI2017]礼物——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4827 https://www.luogu.org/problemnew/show/P3723 题面 ...
- 学习web安全之--初识安全
随笔:随着互联网行业的飞速发展,互联网行业可谓日新月异,然而在繁华的背后,大多的互联网公司对于网络安全还是处于无重视,不作为的阶段,而作为一个程序员,如果也对信息安全视而不见的话,那将是这个公司的噩梦 ...
- HDU2841 (队列容斥)
Visible TreesTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tot ...