dp优化之斜率优化小结

这或许是这几天的济南云斗集训之旅最大的收获吧,若是最后一天的模拟赛文件不会交错也许结局会更好,但在这残酷的现实中却从不会有“如果”一词,母亲以不想让我学了,或许考完今年的 CSP 就可能不学了吧。

本文将效仿《李煜东算法进阶指南》的思路,按照例题层层深入。

P2365 任务安排

题目链接

凡是先考虑朴素算法,这是一个好习惯。

朴素的解法

求出 \(T,C\) 的前缀 \(t,c\),设 \(f_{i,j}\) 为把前 \(i\) 个任务分为 \(j\) 批的最小费用,明显的是第 \(j\) 批任务完成的时间为第 \(j\times S+t_i\) 时刻。

\[f_{i,j}=\min_{0\le k<i} \left \{ f_{k,j-1}+(S\times j+t_i)\times(c_i-c_k)\right \} \]

朴素的解法复杂度 \(O(n^3)\)

本题正解

思考为什么要 \(j\) 这一维,发现 \(j\) 这一维完全是为了求当前这一批完成的时刻。

思考该如何优化,感觉不容易直接求之前此机器启动过几次,但机器每次启动所耗费的时间 \(S\) 最终会累积到之后所有任务完成时间上。所以我们可以将其累加到费用当中。

\(f_i\) 表示把前 \(i\) 个任务分成若干批执行的最小费用,状态转移方程为:

\[f_i=\min_{0\le j<i}\left\{f_j+t_i\times (c_i-c_j)+S\times(c_n-c_j)\right\} \]

下文摘自《李煜东算法进阶指南》:

也就是说我们没有直接求出每批的完成时刻,而是在一批任务“开始”对后续任务产生影响时,就先把费用累加到答案中。这是一种名为“费用前提计算”的经典思想。

很明显这段话可谓相当的晦涩。

该复杂度 \(O(N^2)\)

咦,好尴尬,我似乎没有写过关于此解的的代码。

P10979 任务安排 2

题目链接

与上一题的题意一模一样,但数据加强了。

将上一题的转化方程拆一下,得:

\[f_i=\min_{0\le j<i}\left\{f_j+t_i\times c_i-t_i\times c_j+S\times c_n-S\times c_j\right\} \]

由于 \(f_i\) 的大小只与跟 \(j\) 有关的项有关,其他项都是固定的,可以当作常数,然后再合并同类项,于是得:

\[f_i=\min_{0\le j<i} \left\{f_j-c_j\times (S+t_i)\right\}+t_i\times c_i+S\times c_n \]

让我们把 \(min\) 函数去掉,然后将全部不与 \(j\) 有关的项作为常数项(包括 \(f_i\)),将与 \(j\) 有关的项当作变量,组成一个函数式:

\[f_j=(S+t_i)\times c_j+f_i-c_i\times t_i-S\times c_n \]

在一个以 \(c_j\) 为横坐标(\(x\)),\(f_j\) 为纵坐标(\(y\))的平面直角坐标系当中,这是一条以 \(S+t_i\) 为斜率(\(k\)),以 \(f_i-c_i\times t_i-S\times c_n\) 为截距(\(b\))的直线(\(y=kx+b\))。因此每一个候选的决策都是一个坐标系中的点,即每一个 \(j\) 都对应着一个点 \((c_j,f_j)\),而我们要求的 \(f_i\) 对应每一个点对应直线的截距,每个直线的斜率是固定的,而截距是未知的。综上所述,当截距最小时,\(f_i\) 也最小。

对于三个决策点 \((c_{j_1},f_{j_1})\)\((c_{j_2},f_{j_2})\)\((c_{j_3},f_{j_3})\),设 \(j_1<j_2<j_3\),因为 \(T,C\) 都是正整数所以 \(t\)\(c\) 都有单调性。

探究什么情况时,\(j_2\) 有可能是最优决策:

如上图所示,\(j_2\) 有可能是最优决策,当且仅当:

\[\frac{f_{j_2}-f_{j_1}}{c_{j_2}-c_{j_1}}<\frac{f_{j_3}-f_{j_2}}{c_{j_3}-c_{j_2}} \]

上示的不等式实际上是连接两个决策点连线的斜率,通俗的讲,我们应该维护“链接相邻两点的线段斜率”单调递增的一个“下凸壳”,只有这个下凸壳的顶点才有可能成为最优决策。实际上,对于一条斜率为 \(k\) 的直线,若某个点的左侧线段比 \(k\) 小、右侧线段的斜率比 \(k\) 大,则该顶点就是最优决策。换言之,如果把这条直线和所有线段组成一个排列组成一个序列,那么令结局最小化的定点就出现在按照斜率大小排序时,直线应该排在的位置上。

在本题中,\(j\) 的范围是 \(0\le j<i\),随着 \(i\) 的增大 ,都会有一个新决策出现。因为 \(c\) 的单调性,新决策的单调性一定会大于之前所有决策点的单调性。由于 \(t\) 的单调性,每次的斜率 \(S+t_i\) 也单调递增,如果每次只保留“相邻两点的线段斜率”大于 \(S+t_i\) 的部分,那凸壳的最左端点就一定是最优决策。

综上,对于代码操作,我们建立一个单调队列 \(q\),维护这个下凸壳。

对于每个决策 \(i\)

  1. 检查队头决策 \(q_l\)\(q_{l+1}\),若斜率 $(f_{q_{l+1}}-f_{q_l})/(c_{q_{l+1}}-c_{q_l})\le S+t_i $,则 \(q_l\) 出队,检查新对头。

  2. 取队头 \(q_l\) 为最优决策,计算 \(f_i\)

  3. 将新决策 \(i\) 队尾插入 ,插入前,若 \(q_r\) 不满足下凸性,即 \(q_r\) 是无用决策,就将 \(q_r\) 出队,检查新队尾。

时间复杂度 \(O(n)\)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/882160.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

P3406 海底高铁(差分)

这道题要用到差分,因为反复经过一条路时只需要买一张对应的卡就行了,不用买多张,所以我们可以用差分,算出经过每条路的次数,要注意假设从1到3城市,只经过了道路1和道路2,应该让cha【1】++,cha【3】--; 还有算结果时应该从1到n-1列举每一条路,我最开始就搞错了,还要注…

JPlag:开源的代码抄袭检测工具

一、基本信息•项目地址: https://gitcode.com/gh_mirrors/jp/JPlaghttps://github.com/jplag/JPlag•编程语言:基于Java开发•主要特性:跨平台运行、支持多种文件格式、提供图形用户界面(GUI)和命令行接口、可扩展性强 二、技术特点 •多语言支持:JPlag支持包括Java、C、…

重构谷粒商城01:为何重构谷粒商城

前言:这个系列将使用最前沿的cursor作为辅助编程工具,来快速开发一些基础的编程项目。目的是为了在真实项目中,帮助初级程序员快速进阶,以最快的速度,效率,快速进阶到中高阶程序员。 本项目将基于谷粒商城项目,并且对谷粒商城项目进行二次重构,使其满足最新的主流技术栈…

div设置四个角边框

示例实现 .top-header {background-image:url(../../assets/slider/topHeaderTopLeft.svg), /* 左上角图像 */url(../../assets/slider/topHeaderTopRight.svg), /* 右上角图像 */url(../../assets/slider/topHeaderBottomLeft.svg), /* 左下角图像 */url(../../assets/slider/…

JavaScript根据访问链接不同的后缀参数,展示不同的页面

要求:根据访问者访问不同的后缀链接,展示不同的页面;$(document).ready(function () {// 获取 URL 参数const urlParams = new URLSearchParams(window.location.search);const page = urlParams.get(page) || model; // 默认显示第一个导航项(比分)的内容和图标$(.tab-co…

内外网文件传输方案

文件传输问题:企业内网和外网分开了,如何进行文件快速有效稳定的传输呢?如何 进行文件交换、在线审批、在线审计呢?如何保证安全可控的文件传输、性能及扩展性强、审批审计便捷呢?常见痛点有哪些?纸质申请、线下审批、传递效率很慢,传递成本高, 纸质单据与电子文件脱节…

H3C--堆叠(IRF)

拓扑图 配置流程 配置SW1与SW2堆叠 一、SW1:shutdown 物理端口 配置堆叠优先级,优先级高的成为主设备 创建堆叠逻辑接口,将物理接口加入到堆叠逻辑接口中二、SW1: sysname SW1#irf member 1 priority 6#irf-port 1/1 port group interface FortyGigE1/0/53 port group int…

JavaScript判断iPhone型号机型及iPhone版本Identifier对照

要求:根据用户安装App后,返回的设备型号,判断iPhone版本 实现代码:function getModelValue(last_model) {// 如果last_model不包含"iPhone",则直接返回原值if (!last_model.includes(iPhone)) {return last_model;}// 定义子字符串和对应值的全面映射const mode…

linux部署nacos集群

本次部署 3个nacos节点,然后一个负载均衡器(nginx)代理3个Nacos。集群部署按照前述,做好数据库脚本的初始化、防火墙策略的设置。安装jdk 解压jdk文件 cd /data/soft tar -zxvf jdk-23_linux-x64_bin.tar.gz修改环境变量 vi /etc/profile#install JAVA JDK export JAVA_HOM…

本地部署 Browser-Use WebUI + 本地部署 DeepSeek 实现浏览器AI自动化

前一版采用的是 Deepseek 官方API,由于最近比较火,可能遇到服务器繁忙导致运行不成功,这一版选择通过 Ollama 本地部署的模型 一、安装部署(已安装 python3.11 或以上版本、playwright) 1.下载最新源码包(v1.4及以上版本),解压 https://github.com/browser-use/web-ui/…

QComboBox样式设置

参考 https://blog.csdn.net/xiaopei_yan/article/details/107404698相关qss代码QComboBox{border:1px solid rgb(174,174,174);border-radius: 0;padding-left: 15px;font-size:10pt; } QComboBox::drop-down {subcontrol-origin: padding;subcontrol-position: top right;w…

零售行业数据分析工作模式革新

在零售行业,干数据分析和汇报的小伙伴肯定懂,每个月、每季度、每年都要做各种报告往上交。随着公司业务的拓展,销售的类目从几种到几十种,甚至到上百种,数据量也不断往上涨。以前做个Excel表、画几张图就能搞定的事情,现在光是整理这些数据就够让人头疼了,更别说还要从中…