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

相关推荐
吴可可12330 分钟前
Accumark二次开发环境搭建与API入门
算法
木井巳2 小时前
【动态规划: 线性dp】解码方法
java·算法·leetcode·动态规划·推荐算法
春弦_10 小时前
自用算法整理二
数据结构·算法·图论
hetao173383711 小时前
2026-10-22~23 hetao1733837 的刷题记录
c++·算法
java_nnnn11 小时前
LeetCode刷题滑动窗口(串联所有单词的子串+最小覆盖的子串)Java
算法·leetcode·职场和发展
Navigator_Z12 小时前
LeetCode //C - 1301. Number of Paths with Max Score
c语言·算法·leetcode
卡卡~~12 小时前
“101计划”核心课程实践教材《数据实验结构指导-C++语言版》题目集
开发语言·c++·学习·算法
企业数字化笔记13 小时前
AI视频增强后画质怎么验收?插值基线、伪细节与帧间闪烁的检查方法
人工智能·算法·音视频
学逆向的13 小时前
C 内存属性
c语言·开发语言·算法·网络安全