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

news2024/11/26 5:36:54

斜率优化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.coloradmin.cn/o/1878975.html

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

相关文章

加密与安全_三种方式实现基于国密非对称加密算法的加解密和签名验签

文章目录 国际算法基础概念常见的加密算法及分类签名和验签基础概念常见的签名算法应用场景 国密算法对称加密&#xff08;DES/AES⇒SM4&#xff09;非对称加密&#xff08;RSA/ECC⇒SM2&#xff09;散列(摘要/哈希)算法&#xff08;MD5/SHA⇒SM3&#xff09; Code方式一 使用B…

每日算法-插值查找

1.概念 插值查找是一种改良版的二分查找,其优势在于,对于较为均匀分布的有序数列,能够更快地使得mid中间游标快速接近目标值. 2.计算公式 中间游标计算公式. 公式说明: 公式的主要思路是,以第一次定位mid中间游标为例, 在接近平均分配的情况下,左右游标之间的差值表示总计供…

Linux线程同步【拿命推荐版】

目录 &#x1f6a9;引言 &#x1f6a9;听故事&#xff0c;引概念 &#x1f6a9;生产者消费者模型 &#x1f680;再次理解生产消费模型 &#x1f680;挖掘特点 &#x1f6a9;条件变量 &#x1f680;条件变量常用接口 &#x1f680;条件变量的原理 &#x1f6a9;引言 上一篇…

新的特性使得数据处理更加直观本教程将带你逐步了解如何使用Java Stream API

本人详解 作者:王文峰,参加过 CSDN 2020年度博客之星,《Java王大师王天师》 公众号:JAVA开发王大师,专注于天道酬勤的 Java 开发问题中国国学、传统文化和代码爱好者的程序人生,期待你的关注和支持!本人外号:神秘小峯 山峯 转载说明:务必注明来源(注明:作者:王文峰…

暑假集中备考2024年汉字小达人:来做18道历年选择题备考吧

结合最近几年的活动安排&#xff0c;预计2024年第11届汉字小达人比赛还有4个多月就启动&#xff0c;那么孩子们如何利用这段时间有条不紊地准备汉字小达人比赛呢&#xff1f; 我的建议是充分利用即将到来的暑假&#xff1a;①把小学1-5年级的语文课本上的知识点熟悉&#xff0…

[数据集][目标检测]围栏破损检测数据集VOC+YOLO格式1196张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;1196 标注数量(xml文件个数)&#xff1a;1196 标注数量(txt文件个数)&#xff1a;1196 标注…

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

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

Spring底层原理之bean的加载方式八 BeanDefinitionRegistryPostProcessor注解

BeanDefinitionRegistryPostProcessor注解 这种方式和第七种比较像 要实现两个方法 第一个方法是实现工厂 第二个方法叫后处理bean注册 package com.bigdata1421.bean;import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.…

wordpress企业主题和wordpress免费主题

农业畜牧养殖wordpress主题 简洁大气的农业畜牧养殖wordpress主题&#xff0c;农业农村现代化&#xff0c;离不开新农人、新技术。 https://www.jianzhanpress.com/?p3051 SEO优化wordpress主题 简洁的SEO优化wordpress主题&#xff0c;效果好不好&#xff0c;结果会告诉你…

天气网站爬虫及可视化

摘要&#xff1a;随着互联网的快速发展&#xff0c;人们对天气信息的需求也越来越高。本论文基于Python语言&#xff0c;设计并实现了一个天气网站爬虫及可视化系统。该系统通过网络爬虫技术从多个天气网站上获取实时的天气数据&#xff0c;并将数据进行清洗和存储。同时&#…

Halcon 椭圆

一 椭圆 方差的概念: 例1 两人的5次测验成绩如下&#xff1a;X&#xff1a; 50&#xff0c;100&#xff0c;100&#xff0c;60&#xff0c;50 E(X)72&#xff1b;Y&#xff1a; 73&#xff0c; 70&#xff0c; 75&#xff0c;72&#xff0c;70 E(Y)72。平均成绩相同&#xff0c…

idea 用久了代码提示变慢卡顿优化

idea 用久了代码提示变慢卡顿优化 修改虚拟机配置 修改编译构建堆内存

【proteus经典实战】16X192点阵程序

一、简介 6X192点阵程序通常用于表示高分辨率图像或文字&#xff0c;其中16X表示像素阵列的宽度&#xff0c;192表示每个像素阵列中的点阵数&#xff0c;16X192点阵程序需要一定的编程知识和技能才能编写和调试&#xff0c;同时还需要考虑硬件设备的兼容性和性能等因素。 初始…

智能交通(2)——IntelliLight智能交通灯

论文分享&#xff1a;IntelliLight | Proceedings of the 24th ACM SIGKDD International Conference on Knowledge Discovery & Data Mininghttps://dl.acm.org/doi/10.1145/3219819.3220096摘要 智能交通灯控制对于高效的交通系统至关重要。目前现有的交通信号灯大多由手…

共模和差模的基本概念

电压电流在导体或导线中传播时&#xff0c;存在两种工作形态&#xff1a;共模和差模。电子设备的信号线在进行相互通信时&#xff0c;至少会存在两根导线以形成电传输回路&#xff0c;除此之外&#xff0c;通常还存在第三个导体&#xff0c;即“参考地”。当信号正常传输时&…

JAVA学习笔记-JAVA基础语法-DAY19-File类、递归

第一章 File类 1.1 概述 java.io.File 类是文件和目录路径名的抽象表示&#xff0c;主要用于文件和目录的创建、查找和删除等操作。 1.2 构造方法 public File(String pathname) &#xff1a;通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。public File(St…

go Channel 原理 (一)

Channel 设计原理 不要通过共享内存的方式进行通信&#xff0c;而是应该通过通信的方式共享内存。 在主流编程语言中&#xff0c;多个线程传递数据的方式一般都是共享内存。 Go 可以使用共享内存加互斥锁进行通信&#xff0c;同时也提供了一种不同的并发模型&#xff0c;即通…

python课程设计作业-TCP客户端-服务端通信

说明文档 目录 小组成员分工 作品功能介绍 使用的工具和方法 设计的步骤 课程设计中遇到的问题 结论 1. 小组成员分工 本次课程设计由以下小组成员完成&#xff1a; xxx 2. 作品功能介绍 本次课程设计的作品是一个简单的基于 TCP 协议的客户端-服务端通信示例。通过这个示…

Halcon 特征检测使用

一 Region area: 面积row: 中心的行坐标column: 中心的列坐标width: 区域的宽度(平行于坐标轴)height: 区域的高度(平行于坐标轴)row1: 左上角的行坐标column1: 左上角的列坐标row2: 右下角的行坐标column2: 右下角的列坐标‘ra’; 椭圆的长半轴…

【杂说咋说】中国历史上最古老的十大建筑​,看看你都去过几个?

【杂说咋说】中国历史上最古老的十大建筑​&#xff0c;看看你都去过几个&#xff1f; 中国作为世界四大文明古国之一&#xff0c;历史文化源远流长。在几千年的历史变迁中&#xff0c;中华先祖在神州大地上留下了无数遗迹&#xff0c;其中包括很多古建筑。本期就来介绍一下中…