算法札记:Andrew算法求凸包

学习斜率优化发现要用到凸包,一查发现国外管斜率优化叫凸包优化

‌**具体怎么求凸包?**‌

以最常见的‌求下凸壳 ‌为例(对应DP取min的情况),假设我们的决策点 x 坐标是单调递增的。

‌**核心思想:维护一个单调队列,保证队列中相邻两点连线的斜率是单调递增的。**‌

想象你在从左到右扫描这些点,手里拿着一根线,要把它绷紧在所有点的下方:

  1. 准备阶段 ‌:把所有决策点按 x 坐标从小到大排好序(如果DP过程本身就让 x 单调递增,那就不用额外排序了)。

  2. 逐个加入点 ‌:用一个栈或队列来维护凸包上的点。每加入一个新点 C,就检查它和栈顶两个点 AB 的关系。

  3. 判断凹点并剔除 ‌:计算 AB 连线的斜率 k1BC 连线的斜率 k2

    • 如果 k1 < k2,说明 B 是凸点,保留它,把 C 入栈。
    • 如果 k1 >= k2,说明 B 是凹点(或者共线),它不可能成为最优决策点,把 B 弹出栈,然后继续用新的栈顶两个点和 C 比较,直到满足 k1 < k2 为止。
  4. 重复‌:处理完所有点后,栈里剩下的点就是下凸壳上的点,按顺序排列。


用叉积来判断,避免除法精度问题

实际写代码时,我们一般不用真的算斜率(除法会有精度问题),而是用‌叉积‌来判断三个点的凹凸关系。

对于点 A(x1, y1)B(x2, y2)C(x3, y3),计算向量 ABBC 的叉积:

cross = (x2 - x1) * (y3 - y2) - (y2 - y1) * (x3 - x2)

  • 如果 cross > 0,说明 B 是凸点(下凸壳保留)。
  • 如果 cross <= 0,说明 B 是凹点或共线,应该弹出。

这就是Andrew算法求凸包的核心逻辑,在斜率优化DP里我们通常只维护下半部分凸壳。

相关推荐
keep intensify9 分钟前
最长有效括号
算法·leetcode·动态规划
CoderYanger13 分钟前
A.每日一题:1979. 找出数组的最大公约数
java·程序人生·算法·leetcode·面试·职场和发展·学习方法
猫头虎1 小时前
什么是ZCode for GLM-5.2?
开发语言·人工智能·python·科技·算法·ai编程·ai写作
长不胖的路人甲1 小时前
什么是赫夫曼树(哈夫曼树 / Huffman Tree)
python·算法·霍夫曼树
Warren2Lynch2 小时前
掌握 UML 构造型、标记定义与标记值:面向领域特定建模的 UML 扩展全面指南
大数据·算法·uml
157092511342 小时前
【无标题】
开发语言·python·算法
稚南城才子,乌衣巷风流3 小时前
换根法(Rerooting)算法详解
算法
晓子文集3 小时前
Tushare接口文档:期货交易日历(fut_trade_cal)
大数据·算法
^yi4 小时前
【Linux系统编程】进程状态的理解
算法·僵尸进程·孤儿进程·进程状态·挂起状态·阻塞状态
hhzz4 小时前
机器学习-算法模型系列文章:04-KNN 不做标准化就跑KNN?你的模型正在被一个特征“独裁“
人工智能·算法·机器学习