斜率优化DP——AcWing 303. 运输小猫

斜率优化DP

定义

斜率优化DP(Slope Optimization Dynamic Programming)是一种高级动态规划技巧,用于优化具有特定形式的状态转移方程。它主要应用于那些状态转移涉及求极值(如最小值或最大值)的问题中,通过分析状态转移函数的斜率特性,将原本需要进行多次比较的操作转化为对斜率的管理,从而减少计算量。斜率优化的核心在于利用函数的单调性,通过维护一个数据结构(如单调队列)来避免重复计算,达到优化的目的。

运用情况

  1. 最优化问题:当动态规划的状态转移涉及求解最小值或最大值,且转移方程可表达为线性或近似线性关系时。
  2. 序列问题:例如,在序列中选择一段区间,使得区间内满足某种条件的子序列和最大或最小。
  3. 费用最小化问题:如求解完成某任务序列的最小花费,其中选择下一个任务的成本可能依赖于之前的选择。
  4. 具有特殊结构的问题:如某些问题的状态转移可以通过分析状态间的关系转换为斜率的比较和更新。

注意事项

  1. 状态和转移方程:明确问题的状态定义和状态转移方程,确保它们适合斜率优化。
  2. 单调性分析:分析状态转移函数的斜率变化,确定如何维护一个单调队列或其他数据结构来避免无效计算。
  3. 边界处理:注意处理状态转移的边界条件,特别是状态转移开始和结束时的特殊情况。
  4. 数据结构选择:根据问题的具体情况选择合适的数据结构(如单调队列)来维护关键信息。
  5. 复杂度控制:确保斜率优化后的时间复杂度优于原始DP,避免过度优化导致的复杂度上升。

解题思路

  1. 理解问题:首先,深入理解问题背景和求解目标,识别出问题是否适合斜率优化。
  2. 状态定义:定义合适的DP状态和状态转移方程,注意状态转移应能表达为某种极值问题。
  3. 斜率分析:分析状态转移方程中涉及的变量关系,识别出与“斜率”相关的模式,如线性函数、单调性等。
  4. 设计优化策略:根据斜率特性设计数据结构(通常是单调队列)来维护中间状态,避免重复计算。
  5. 实现代码:编写代码实现动态规划过程,同时集成斜率优化机制,注意正确处理边界和特殊情况。
  6. 验证与优化:测试代码,确保正确性,并根据实际情况调整优化策略以进一步提高效率。

AcWing 303. 运输小猫

题目描述

AcWing 303. 运输小猫 - AcWing

运行代码

#include <cstring>
#include <iostream>
#include <algorithm>using namespace std;typedef long long LL;const int N = 100010, M = 100010, P = 110;int n, m, p;
LL d[N], t[N], a[N], s[N];
LL f[P][M];
int q[M];LL get_y(int k, int j)
{return f[j - 1][k] + s[k];
}int main()
{scanf("%d%d%d", &n, &m, &p);for (int i = 2; i <= n; i ++ ){scanf("%lld", &d[i]);d[i] += d[i - 1];}for (int i = 1; i <= m; i ++ ){int h;scanf("%d%lld", &h, &t[i]);a[i] = t[i] - d[h];}sort(a + 1, a + m + 1);for (int i = 1; i <= m; i ++ ) s[i] = s[i - 1] + a[i];memset(f, 0x3f, sizeof f);for (int i = 0; i <= p; i ++ ) f[i][0] = 0;for (int j = 1; j <= p; j ++ ){int hh = 0, tt = 0;q[0] = 0;for (int i = 1; i <= m; i ++ ){while (hh < tt && (get_y(q[hh + 1], j) - get_y(q[hh], j)) <= a[i] * (q[hh + 1] - q[hh])) hh ++ ;int k = q[hh];f[j][i] = f[j - 1][k] - a[i] * k + s[k] + a[i] * i - s[i];while (hh < tt && (get_y(q[tt], j) - get_y(q[tt - 1], j)) * (i - q[tt]) >=(get_y(i, j) - get_y(q[tt], j)) * (q[tt] - q[tt - 1])) tt -- ;q[ ++ tt] = i;}}printf("%lld\n", f[p][m]);return 0;
}

代码思路

  1. 输入处理:

    • 首先读入山的数量 n、猫的数量 m、饲养员的数量 p
    • 然后读入每两座相邻山之间的距离,并累加得到从1号山到每座山的总距离 d[]
    • 对于每只猫,读入它停留的山的编号 h 和停止玩耍的时刻 t,并计算出相对于1号山的等待时间差 a[i] = t[i] - d[h]
    • 对这些等待时间差进行排序,同时计算累积和 s[]
  2. 动态规划初始化:初始化二维数组 f[j][i] 来存储前 i 只猫被前 j 个饲养员接走的最小等待时间总和。这里 f[j][0] = 0,表示没有猫时等待时间为0。

  3. 单调队列优化动态规划:

    • 使用单调递减的队列 q[] 来存储可能成为最优解的状态索引。队列中的元素代表当前考虑的猫的下标。
    • 遍历每增加一个饲养员 (j 从1到 p) 的情况,对于每只猫 (i 从1到 m),计算将其加入到当前饲养员的最优解中需要增加的等待时间。
    • 通过维护队列保证每次选择的都是可能产生最小等待时间的猫的组合。队列中的更新基于斜率(即增加一个猫带来的收益变化)来进行,确保队头总是最优解的一部分。
    • 计算 f[j][i] 时,利用队列中的信息避免重复计算,实现状态转移的优化。
  4. 输出结果:最终答案存储在 f[p][m] 中,即所有猫被 p 个饲养员接走的最小等待时间总和。

改进思路

  1. 内存优化:当 M 和 P 的值较大时,f[P][M] 的空间复杂度可能较高。可以考虑滚动数组或者只保留必要的状态来减少空间使用。例如,由于状态转移只与前一状态有关,可以只保留两行或一维数组来交替存储上一行和当前行的状态。

  2. 细节优化:在计算斜率时,直接计算斜率可能导致浮点运算,影响效率和精度。可以通过比较差值而非直接计算斜率来优化,即比较 (f[j-1][k] - f[j-1][k-1]) 与 (a[k] - a[k-1]) 来判断单调性,避免浮点运算。

  3. 输入处理的效率:对于大数组的读入,可以考虑使用更快的IO方式,如 scanf 替换为 read 加缓冲读取,或者使用 ios::sync_with_stdio(false) 禁用C++标准库与C标准库的同步,提升读写速度。

  4. 避免重复计算:确认在计算斜率和更新状态时,是否有进一步的重复计算可以避免。例如,是否可以通过更精细的数据结构或额外的变量来避免某些全局查找或重复的计算过程。

  5. 代码可读性和维护性:

    • 添加更多的注释,特别是对于算法核心逻辑和复杂的数据结构操作部分,提高代码的可读性和后期维护的便捷性。
    • 函数化拆分复杂的逻辑,比如将单调队列的维护、状态转移逻辑封装成单独的函数,使代码结构更加清晰。
  6. 性能测试与瓶颈分析:实施性能测试,确定程序的瓶颈所在,可能是I/O操作、内存访问、或是特定的计算环节。根据测试结果,针对性地进行优化。

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

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

相关文章

CesiumJS【Basic】- #028 天空盒

文章目录 天空盒1 目标2 代码2.1 main.ts3 资源天空盒 1 目标 配置显示天空盒 2 代码 2.1 main.ts import * as Cesium from cesium;// 创建 Cesium Viewer 并配置地形数据和天空盒 const viewer = new Cesium.Viewer(

理解抽象工厂设计模式

目录 抽象工厂模式抽象工厂模式结构抽象工厂模式适合应用场景抽象工厂模式优缺点练手题目题目描述输入描述输出描述提示信息题解 抽象工厂模式 抽象工厂模式是一种创建型设计模式&#xff0c; 它能创建一系列相关的对象&#xff0c; 而无需指定其具体类。 抽象工厂模式结构 抽…

自定义一个MyBaits脱敏插件

自定义一个MyBaits脱敏插件 用于对查询结果中的敏感数据进行脱敏处理。这个插件将拦截ResultSetHandler对象的处理结果&#xff0c;对某些敏感字段进行脱敏。 插件实现步骤 创建脱敏插件类。注册插件。 1. 创建脱敏插件类 首先&#xff0c;我们创建一个自定义插件类 DataM…

深入理解策略梯度算法

策略梯度&#xff08;Policy Gradient&#xff09;算法是强化学习中的一种重要方法&#xff0c;通过优化策略以获得最大回报。本文将详细介绍策略梯度算法的基本原理&#xff0c;推导其数学公式&#xff0c;并提供具体的例子来指导其实现。 策略梯度算法的基本概念 在强化学习…

【Python3的内置函数和使用方法】

目录 Python 特点 Python 中文编码 Python 变量类型 Python列表 Python 元组 元组是另一个数据类型&#xff0c;类似于 List&#xff08;列表&#xff09; Python 字典 Python数据类型转换 Python 运算符 Python算术运算符 Python比较运算符 Python赋值运算符 Pyt…

一篇就够了,为你答疑解惑:锂电池一阶模型-离线参数辨识(附代码)

锂电池一阶模型-参数离线辨识 背景模型简介数据收集1. 最大可用容量实验2. 开路电压实验3. 混合动力脉冲特性实验离线辨识对应模型对应代码总结下期预告文章字数有点多,耐心不够的谨慎点击阅读。 下期继续讲解在线参数辨识方法。 背景 最近又在开始重新梳理锂电池建模仿真与S…

使用stat()函数的例子

代码&#xff1a; #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <stdio.h>int main(void) {struct stat st;if(-1stat("test.txt",&st)){printf("获得文件状态失败\n");return -1;}printf(&q…

Unidbg调用-补环境V2

1.B站 内部依赖自定义的SignedQuery对象,需要找到apk中的类并补充环境。 package com.nb.demo;import com.github.unidbg.AndroidEmulator

llama3模型部署时遇到的问题及解决方案

在llama3模型部署时&#xff0c;会遇到一系列问题&#xff0c;这里就作者所遇到的问题与解决方法分享一下。 注意&#xff1a;这里是从llama3 github主页上给的方法一步步做的&#xff0c;不适用于其他部署大模型的方法。 文章目录 ERROR 403&#xff1a;Forbidden安装依赖时出…

洛谷 P1548 [NOIP1997 普及组] 棋盘问题

题目 洛谷 P1548 [NOIP1997 普及组] 棋盘问题 [NOIP1997 普及组] 棋盘问题 题目背景 NOIP1997 普及组第一题 题目描述 设有一个 N M N \times M NM 方格的棋盘 ( 1 ≤ N ≤ 100 , 1 ≤ M ≤ 100 ) (1≤N≤100,1≤M≤100) (1≤N≤100,1≤M≤100) 求出该棋盘中包含有多少个正…

MySQL高级-MVCC-undo log 版本链

文章目录 1、undo log2、undo log 版本链2.1、然后&#xff0c;有四个并发事务同时在访问这张表。2.1.1、修改id为30记录&#xff0c;age改为32.1.2、修改id为30记录&#xff0c;name改为A32.1.3、修改id为30记录&#xff0c;age改为10 2.2、总结 1、undo log 回滚日志&#xf…

文件系统(操作系统实验)

实验内容 &#xff08;1&#xff09;在内存中开辟一个虚拟磁盘空间作为文件存储器&#xff0c; 在其上实现一个简单单用户文件系统。 在退出这个文件系统时&#xff0c;应将改虚拟文件系统保存到磁盘上&#xff0c; 以便下次可以将其恢复到内存的虚拟空间中。 &#xff08;2&…

数字孪生煤矿智能化综合管控平台

煤矿可视化通过图扑 HT 实现实时数据集成和三维建模仿真&#xff0c;呈现井下环境、设备状态和生产状况等多维度数据&#xff0c;帮助管理人员进行直观监控和精准分析。该技术提升了运营效率和安全水平&#xff0c;为煤矿作业提供了智能化的管理解决方案&#xff0c;有助于减少…

黑马点评DAY1|Redis入门、Redis安装

什么是Redis&#xff1f; redis是一种键值型数据库&#xff0c;内部所存的数据都是键值对的形式&#xff0c;例如&#xff0c;我们可以把一个用户数据存储为如下格式&#xff1a; 键值id$1600name张三age21 但是这样的存储方式&#xff0c;数据会显得非常松散&#xff0c;因…

云计算HCIE+RHCE学员的学习分享

大一下学期&#xff0c;我从学长嘴里了解到誉天教育&#xff0c;当时准备考RHCE&#xff0c;我也了解了很多培训机构&#xff0c;然后学长强烈给我推荐誉天&#xff0c;我就在誉天报名了RHCE的课程。 通过杨峰老师的教学&#xff0c;我学到了许多Linux知识&#xff0c;也了解了…

笔记本电脑部署VMware ESXi 6.0系统

正文共&#xff1a;888 字 18 图&#xff0c;预估阅读时间&#xff1a;1 分钟 前面我们介绍了在笔记本上安装Windows 11操作系统&#xff08;Windows 11升级不了&#xff1f;但Win10就要停服了啊&#xff01;来&#xff0c;我教你&#xff01;&#xff09;&#xff0c;也介绍了…

【单片机毕业设计选题24037】-基于STM32的电力系统电力参数无线监控系统

系统功能: 系统上电后&#xff0c;OLED显示“欢迎使用电力监控系统请稍后”&#xff0c;两秒后显示“Waiting..”等待ESP8266初始化完成&#xff0c; ESP8266初始化成功后进入正常页面显示&#xff0c; 第一行显示电压值&#xff08;单位V&#xff09; 第二行显示电流值&am…

互联网大厂核心知识总结PDF资料

我们要敢于追求卓越&#xff0c;也能承认自己平庸&#xff0c;不要低估3&#xff0c;5&#xff0c;10年沉淀的威力 hi 大家好&#xff0c;我是大师兄&#xff0c;大厂工作特点是需要多方面的知识和技能。这种学习和积累一般人需要一段的时间&#xff0c;不太可能一蹴而就&…

VMware虚拟机迁移:兼用性踩坑和复盘

文章目录 方法失败情况分析&#xff1a;参考文档 方法 虚拟机关机&#xff0c;整个文件夹压缩后拷贝到新机器中&#xff0c;开机启用即可 成功的情况&#xff1a; Mac (intel i5) -> Mac (intel i7)Mac (intel, MacOS - VMware Fusion) -> DELL (intel, Windows - VMw…

Zynq7000系列FPGA中的DMA控制器简介(二)

AXI互连上的DMA传输 所有DMA事务都使用AXI接口在PL中的片上存储器、DDR存储器和从外设之间传递数据。PL中的从设备通过DMAC的外部请求接口与DMAC通信&#xff0c;以控制数据流。这意味着从设备可以请求DMA交易&#xff0c;以便将数据从源地址传输到目标地址。 虽然DMAC在技术…