算法札记: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里我们通常只维护下半部分凸壳。

相关推荐
aaaameliaaa7 小时前
计算斐波那契数(递归、迭代)(1,1,2,3,5.....)
c语言·开发语言·笔记·算法·排序算法
Jerry8 小时前
LeetCode 977. 有序数组的平方
算法
Turbo正则8 小时前
群论学习入门 | 群论与李群的基本概念
人工智能·学习·算法·抽象代数
sugar__salt8 小时前
手撕字符串算法:反转、回文、验证回文 Ⅱ 完整拆解
javascript·算法·面试·职场和发展
To_OC8 小时前
从一行报错开始,把字符串反转、回文算法连带着包装类一起捋明白
javascript·算法·api
LCG米8 小时前
机器人控制系统与运动规划:从RRT算法到ROS move_base实战
算法·机器人
QiLinkOS8 小时前
第三视觉理解徐玉生与他的商业活动(26)
大数据·c++·人工智能·算法·开源协议
手写码匠9 小时前
手写 LLM 结构化输出引擎 —— 从 JSON Schema 约束到类型安全的数据提取
人工智能·深度学习·算法·aigc
zhiSiBuYu05179 小时前
重排序(Rerank)提升检索准确率实战指南
开发语言·python·算法
月疯9 小时前
华为手环的部分功能
算法