算法札记:Andrew算法求凸包

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

相关推荐
longlongzihan6 小时前
LeetCode 17电话号码的字母组合:回溯算法(DFS)详解
c++·算法·leetcode·深度优先
封印师请假去地球钓鱼6 小时前
边解边变的问题:从“决策依赖“一词出发
人工智能·算法
今晚打老虎7 小时前
c++之提高A(前缀和)(第三课)
数据结构·c++·算法
不会就选b8 小时前
算法日常・每日刷题--<贪心>26
数据结构·算法
hetao173383710 小时前
2026-09-29 hetao1733837 的刷题记录
c++·算法
欣欣之王来了10 小时前
AI合规专项:AI算法透明度的合规要求
人工智能·算法
wzdark10 小时前
分块思想在算法优化中的实践与应用4
算法
Because_of_Her111 小时前
dfs-洪水填充技巧
笔记·算法·深度优先·洪水填充
小静AI工程实验室11 小时前
RSA 算法详解:从模幂原理到 OAEP 加密、PSS 签名与 Python 实验
python·算法
xzal1211 小时前
GESP Python笔记
笔记·python·算法