1 条题解
-
0
自动搬运
来自洛谷,原作者为

Eastern
满船轻梦压星河,偷捧时间煮酒喝搬运于
2025-08-24 22:12:04,当前版本为作者最后更新于2020-02-20 09:38:03,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
[做法] GarsiaWachs算法
*更多内容及证明见后文
- 找到满足 的最小下标
- 找到满足 的最大
- 从列表中清除
- 在 之后插入
- 和 可以用 处理
例:
186 64 35 32 103 3 1 67 64 103 2 131 103 -1 234 186 1 420 代码实现: 通过 模拟上述过程
因为删除 和 插入 操作速度较慢,代码需要O2优化
我太菜了#include <bits/stdc++.h>//懒 using namespace std; int n, k, j; int ans, sum; vector<int> v; int read() { int x = 0, f = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();} while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); return x * f; } int main() { n = read(); v.push_back(INT_MAX - 1); for (int i = 1; i <= n; i++) v.push_back(read()); v.push_back(INT_MAX); while (n-- > 1) { for (k = 1; k <= n; k++) if (v[k - 1] < v[k + 1]) break; sum = v[k] + v[k - 1]; for (j = k - 1; j >= 0; j--) if (v[j] > v[k] + v[k - 1]) break; v.erase(v.begin() + k - 1); v.erase(v.begin() + k - 1); v.insert(v.begin() + j + 1, sum); ans += sum; } printf("%d", ans); return 0; }加西亚-瓦克斯(GarsiaWachs)算法.
这种算法是基于最优二叉树提出的,有一个概念叫做
二叉树中预期比较次数

根节点的
二叉查找树中给定几个概率值, 和
表示查找参数是 的概率, 表示查找参数介于 概率
查找预期比较次数是
${\sum_{j=1}^n p_j(level+1)+{\sum_{k=0}^n}q_k(level_k)}$
针对外节点的,其实这理解起来也不难,外节点是直接暴露在外面的
根据只要知道它的层数,比如 两个外节点都在第 层,这时候只要
就可以知道 出现的概率,也就可以知道比较次数了
是针对内节点的,一定要通过外节点才能进入内节点,所以要
上述公式叫 树的成本,预期比较次数为
外节点:
内节点:
二者的和就是这个树的成本
加西亚瓦克斯算法就是上述树的成本中, 时候的特例
引理一,最优二叉树的转化
如果 ,则在每棵最优树中,
如果 ,则在某些最优树中,
证明方法,看一个二叉树的剪裁

不妨设 ,并且考虑
那么树的形状一定如上图所示, 为右孩子
这个时候如果按照图中的方式剪裁,两条线中的部分裁掉
让左子节点 成为新的 ,并且 部分裁掉
使得 节点上浮,并且 节点下沉一个单位
不妨设 是一个权值为 的子树, ,这是显然的
因为我们假定 ,那么在左边的外节点权值更大
这样裁剪之后,总的权值变化包括 个部分
1) 裁掉,}
2) 上浮,
3) 下沉,
$$\Delta = -w-q_k(l_k-l_{k+1}-1)+q_{k+1} \le -q_{k-1}-q_k(l_k-l_{k-1}-1)+q_{k+1}\le q_{k+1} - q{k-1} $$如果 ,显然不是最优的,矛盾
另外,如果 ,则已经将一棵最优树转变成为另一颗了
和 这个层次上等价,,构成最优树
引理二,树的旋转调整分支高度
假定 和 是满足 的下标,并且满足
- 对于
- 对于
于是,存在一颗满足 的最优树,同时,它还满足以下条件之一
且 为左孩子
证明方法,从引理一直到 ,存在满足 的最优树
对于 而言,还有 ,因此有
其次,我们关注树的层次,如下图所示

先看如图所示的三层结构,对于满足 的 有
,假设 是满足 且小于 的最小下标
于是,对于 ,有 并且 为左孩子,或者
,这样我们可以通过二叉树旋转等操作
让部分节点上升,部分节点下降
如果让s所在的分支下降,t所在的分支上升的话
,因为,所以
如果 ,所以 ,次时能得到更优的二叉树
旋转之后,
再看最后一个部分,如果 并且 是有孩子的话,则一定有如下情况

如果旋转二叉树,让 下降,让 这个分支上升
,此时二叉树并不是最优的,和假设矛盾
引理三,加西亚瓦克斯算法核心
如上所述,可以考虑删除 和 并且在 之后插入
所得到的概率 $(q_0',\ldots ,q_{n-1}')=(q_0,\ldots,q_{j-1}, q_{k-1}+q_k,q_j,\ldots,q_{k-2},q_k+1,\ldots,q_n)$
于是,$C(q_0',\ldots,q_{n-1}')\le C(q_0,\ldots,q_n)-(q_{k-1}+q_k)$
排列方式
更优
这就很简单了,根据引理二,如果是类型的,只需要重命名这些叶节点就可以
如果是类型的呢?可以通过旋转二叉树的方式,让 这两个叶子对
上升一个高度,实际上就是在 这个高度上,减掉 ,然后向左移动
在 后面插入即可
引理四
任何一个排列方式如引理三所述的树,都可以转化成为
成本相同,叶子排列顺序为 的树
-
如果 ,显然成立
-
如果不相等,因为 (引理二条件)
↑ ↑ j k - 1的下标表示如上所示,所以对于 ,有
于是根据引理,有 ,其中 是 的级别,并且
对于 , 是 的级别
如果 ,都在同一级上
替换序列
否则,假定 ,,令 ,并且
是节点 的公共级别,使得
,最后可以通过循环位移操作,使得
变成
有看不懂的别找我这个 快敲死我了终
- 1
信息
- ID
- 4574
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者