AcWing 凸包优化DP相关问题 301. 任务安排2

这个题目数据量比较大,还是平方级DP肯定TLE没跑,所以采用凸包优化的方式压缩时间复杂度,凸包优化思路有点绕,梳理半天记录一下自己的分析笔记凸包点序列中查找和直线的切点的方法最后是Python 代码from collections import dequeN = int(input())S = int(input())St = [0] * NSc = [0] * Nfor i in range(N): St[i], Sc[i] = map(int, input()
摘要由CSDN通过智能技术生成

这个题目数据量比较大,还是平方级DP肯定TLE没跑,所以采用凸包优化的方式压缩时间复杂度,凸包优化思路有点绕,梳理半天记录一下自己的分析笔记

凸包点序列中查找和直线的切点的方法

最后是Python 代码,这个题因为斜率K是一直变大的,所以还有个优化,凸包序列中的点如果斜率小于当前迭代i时候计算出来的斜率,那后续的直线不可能切到这些点上,因此把斜率较小的点全部从队列尾删掉,实际测试好像有没有这个优化,运行时间都没差多少

from collections import deque

N = int(input())
S = int(input())

St = [0] * N
Sc = [0] * N
for i in range(N):
    St[i], Sc[i] = map(int, input().split())
for i in range(1, N):
    St[
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用GaoCp Math Package中的Vector2d向量库以及Melkman算法来求凸包,以下是示例代码: ```c++ #include <bits/stdc++.h> #include <gcmp.hpp> using namespace std; using namespace gcmp; const int N = 1e5 + 5; int n, top; Vector2d p[N], q[N], stk[N]; void melkman() { int front = 1, back = 1; stk[1] = q[1]; for (int i = 2; i <= n; ++i) { // 加入左侧的点 if (q[i].x > stk[front].x) { stk[--front] = q[i]; } else if (q[i].x < stk[front].x) { stk[++front] = q[i]; } else { stk[front] = q[i]; } // 加入右侧的点 if (q[n - i + 1].x > stk[back].x) { stk[++back] = q[n - i + 1]; } else if (q[n - i + 1].x < stk[back].x) { stk[--back] = q[n - i + 1]; } else { stk[back] = q[n - i + 1]; } } top = 0; for (int i = front; i <= back; ++i) { stk[++top] = stk[i]; } } bool cmp(Vector2d a, Vector2d b) { double c = a.x - b.x; if (c == 0) return a.y < b.y; return c < 0; } int main() { scanf("%d", &n); for (int i = 1; i <= n; ++i) { scanf("%lf%lf", &p[i].x, &p[i].y); } sort(p + 1, p + n + 1, cmp); int k = 0; for (int i = 1; i <= n; ++i) { while (k > 1 && (p[i] - q[k - 1]).cross(q[k] - q[k - 1]) <= 0) { --k; } q[++k] = p[i]; } int t = k; for (int i = n - 1; i >= 1; --i) { while (k > t && (p[i] - q[k - 1]).cross(q[k] - q[k - 1]) <= 0) { --k; } q[++k] = p[i]; } melkman(); for (int i = 1; i <= top; ++i) { printf("%.0f %.0f\n", stk[i].x, stk[i].y); } return 0; } ``` 这段代码使用了GaoCp Math Package中的Vector2d向量库和Melkman算法来求凸包。具体思路可以参考以下步骤: 1. 将所有点按横坐标排序。 2. 对排序后的点依次进行半平面交,得到凸包的上下两个部分。 3. 对上下两个部分使用Melkman算法进行合并。 4. 最后得到的栈中就是凸包的所有点。 需要注意的是,在使用Melkman算法进行合并时,需要分别从左至右和从右至左两次进行,最后将结果合并。 希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值