【图论】【堆优化的单源路径】LCP 20. 快速公交

作者推荐

【广度优先搜索】【网格】【割点】【 推荐】1263. 推箱子

LCP 20. 快速公交

小扣打算去秋日市集,由于游客较多,小扣的移动速度受到了人流影响:
小扣从 x 号站点移动至 x + 1 号站点需要花费的时间为 inc;
小扣从 x 号站点移动至 x - 1 号站点需要花费的时间为 dec。
现有 m 辆公交车,编号为 0 到 m-1。小扣也可以通过搭乘编号为 i 的公交车,从 x 号站点移动至 jump[i]*x 号站点,耗时仅为 cost[i]。小扣可以搭乘任意编号的公交车且搭乘公交次数不限。
假定小扣起始站点记作 0,秋日市集站点记作 target,请返回小扣抵达秋日市集最少需要花费多少时间。由于数字较大,最终答案需要对 1000000007 (1e9 + 7) 取模。
注意:小扣可在移动过程中到达编号大于 target 的站点。
示例 1:
输入:target = 31, inc = 5, dec = 3, jump = [6], cost = [10]
输出:33
解释: 小扣步行至 1 号站点,花费时间为 5; 小扣从 1 号站台搭乘 0 号公交至 6 * 1 = 6 站台,花费时间为 10; 小扣从 6 号站台步行至 5 号站台,花费时间为 3; 小扣从 5 号站台搭乘 0 号公交至 6 * 5 = 30 站台,花费时间为 10; 小扣从 30 号站台步行至 31 号站台,花费时间为 5; 最终小扣花费总时间为 33。
示例 2:
输入:target = 612, inc = 4, dec = 5, jump = [3,6,8,11,5,10,4], cost = [4,7,6,3,7,6,4]
输出:26
解释: 小扣步行至 1 号站点,花费时间为 4; 小扣从 1 号站台搭乘 0 号公交至 3 * 1 = 3 站台,花费时间为 4; 小扣从 3 号站台搭乘 3 号公交至 11 * 3 = 33 站台,花费时间为 3; 小扣从 33 号站台步行至 34 站台,花费时间为 4; 小扣从 34 号站台搭乘 0 号公交至 3 * 34 = 102 站台,花费时间为 4; 小扣从 102 号站台搭乘 1 号公交至 6 * 102 = 612 站台,花费时间为 7; 最终小扣花费总时间为 26。
提示:
1 <= target <= 109
1 <= jump.length, cost.length <= 10
2 <= jump[i] <= 106
1 <= inc, dec, cost[i] <= 106

单源路径

分析从0到x的最小花费时间。
情况一:没有坐公交,inc*target。
情况二:做了公交,枚举最后一趟公交i,对于公交只需要考虑三种情况:
1,x就在公交站,就在x下车。
2,在x的前一站下车,x/ jump[i]*jump[i]。
3,在x的后一站下车x/ jump[i]*jump[i]+1。
假定x的前一站是x1,前前一站是x2。
{ x 2 / j u m p [ i ] → i n c x 1 / j u m p [ i ] → c o s t [ i ] x 1 i n c + c o s t [ i ] x 1 下车 x 2 / j u m p [ i ] → c o s t [ i ] x 2 → i n c × j u m p [ i ] x 1 i n c ∗ j u m p [ i ] + c o s t [ i ] x 2 下车 \begin{cases} x2/jump[i]^{inc}_{\rightarrow} x1/jump[i]^{cost[i]}_{\rightarrow} x1 & inc+cost[i] & x1下车\\ x2/jump[i] ^{cost[i]}_{\rightarrow} x2 ^{inc\times jump[i]}_{\rightarrow} x1 & inc*jump[i]+cost[i] & x2下车 \end{cases} {x2/jump[i]incx1/jump[i]cost[i]x1x2/jump[i]cost[i]x2inc×jump[i]x1inc+cost[i]incjump[i]+cost[i]x1下车x2下车
情况三证明类似。

共四种情况:
{ 直接处理 没坐车 出发站点 刚好在站点 2 个下车站点 不在车站 \begin{cases} 直接处理 & 没坐车\\ 出发站点 & 刚好在站点\\ 2个下车站点 & 不在车站\\ \end{cases} 直接处理出发站点2个下车站点没坐车刚好在站点不在车站

堆优化的单源路径

由于节点数未知,所以无法用朴素单源路径。初始状态无法知道起点(0)的相连节点,所以求0的最短路径,只能求target的最短路径。

代码

核心代码

typedef pair<long long, int> PAIRLLI;
class Solution {
public:int busRapidTransit(int target, int inc, int dec, vector<int>& jump, vector<int>& cost) {std::priority_queue<PAIRLLI, vector<PAIRLLI>, greater<PAIRLLI>> minHeap;minHeap.emplace(0, target);while (minHeap.size()){const long long llDist = minHeap.top().first;const int iCur = minHeap.top().second;minHeap.pop();if (m_mDis.count(iCur)){continue;}m_mDis[iCur] = llDist;if (0 == iCur){break;}		minHeap.emplace(llDist+(long long)inc*iCur, 0);for (int i = 0 ; i < jump.size(); i++){const int x1 = iCur / jump[i] * jump[i];				if (x1 != iCur){minHeap.emplace(llDist + ((long long)inc) * (iCur - x1) , x1 );minHeap.emplace(llDist + ((long long)dec) * (x1 + jump[i] - iCur),x1 +jump[i]);}else{minHeap.emplace(llDist + cost[i], x1/jump[i]);}}}return m_mDis[0]%1000'000'007;}unordered_map<int, long long> m_mDis;
};

测试用例

template<class T,class T2>
void Assert(const T& t1, const T2& t2)
{assert(t1 == t2);
}template<class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{if (v1.size() != v2.size()){assert(false);return;}for (int i = 0; i < v1.size(); i++){Assert(v1[i], v2[i]);}}int main()
{int target,  inc,  dec;vector<int> jump,  cost;{Solution sln;target = 31, inc = 5, dec = 3, jump = { 6 }, cost = { 10 };auto res = sln.busRapidTransit(target, inc, dec, jump, cost);Assert(33, res);}{Solution sln;target = 612, inc = 4, dec = 5, jump = { 3, 6, 8, 11, 5, 10, 4 }, cost = { 4, 7, 6, 3, 7, 6, 4 };auto res = sln.busRapidTransit(target, inc, dec, jump, cost);Assert(26, res);}{Solution sln;target = 1000000000, inc = 1, dec = 1, jump = { 2 }, cost = { 1000000 };auto res = sln.busRapidTransit(target, inc, dec, jump, cost);Assert(10953125, res);}{Solution sln;target = 954116209, inc = 725988, dec = 636911, jump = { 524425, 158389 }, cost = { 41881, 941330 };auto res = sln.busRapidTransit(target, inc, dec, jump, cost);Assert(556489627, res);}}

小优化

可以跳过下车站,直接处理上车站。性能更优化,但排错难道增加。

typedef pair<long long, int> PAIRLLI;
class Solution {
public:int busRapidTransit(int target, int inc, int dec, vector<int>& jump, vector<int>& cost) {std::priority_queue<PAIRLLI, vector<PAIRLLI>, greater<PAIRLLI>> minHeap;minHeap.emplace(0, target);while (minHeap.size()){const long long llDist = minHeap.top().first;const int iCur = minHeap.top().second;minHeap.pop();if (m_mDis.count(iCur)){continue;}m_mDis[iCur] = llDist;if (0 == iCur){break;}		minHeap.emplace(llDist+(long long)inc*iCur, 0);for (int i = 0 ; i < jump.size(); i++){const int x1 = iCur / jump[i] * jump[i];	minHeap.emplace(llDist + ((long long)inc) * (iCur - x1) + cost[i], x1 / jump[i]);if (x1 != iCur){minHeap.emplace(llDist + ((long long)dec) * (x1 + jump[i] - iCur) + cost[i], x1 / jump[i] + 1);					}			}}return m_mDis[0]%1000'000'007;}unordered_map<int, long long> m_mDis;
};

2023年3月版

class Solution {
public:
const long long M = 1e9 + 7;
int busRapidTransit(int target, int inc, int dec, vector& jump, vector& cost) {
std::priority_queue<std::pair<long long, int>, std::vector<std::pair<long long, int>>, std::greater<std::pair<long long, int>>> que;
std::unordered_map<int,long long> mPosTime;
auto append = [&](long long llTime, int iPos)
{
bool bHas = mPosTime.count(iPos);
if (bHas && (llTime >= mPosTime[iPos]))
{
return;
}
que.emplace(llTime, iPos);
mPosTime[iPos] = llTime;
};
append(0, target);
long long llRet = inc * (long long)target;
for (; que.size()😉
{
const long long llTime = que.top().first;
const int iPos = que.top().second;
que.pop();
if (llTime > llRet)
{
break;
}
llRet = min(llRet, llTime + inc*(long long)iPos);
for (int i = 0; i < jump.size(); i++)
{
const int iPreCur = iPos / jump[i] * jump[i];
if (iPreCur == iPos)
{
append(llTime + cost[i], iPos / jump[i]);
continue;
};
append(llTime + cost[i] + (long long)inc*(iPos - iPreCur), iPos / jump[i]);
const int iNext = iPreCur + jump[i];
append(llTime + cost[i] + (long long)dec*(iNext - iPos), iPos / jump[i] + 1);
}
}
return llRet % M;
}

};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

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

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

相关文章

计算机组成原理(14)----总线

目录 一.总线的物理实现 二.总线概述 三.总线的特性 四.总线的分类 &#xff08;1&#xff09;按数据传输格式分类 •串行总线 •并行总线 &#xff08;2&#xff09;按总线功能分类 •片内总线 •系统总线 系统总线的结构 •通信总线 &#xff08;3&#xff09;按…

从软硬件以及常见框架思考高并发设计

目录 文章简介 扩展方式 横向扩展 纵向扩展 站在软件的层面上看 站在硬件的层面上看 站在经典的单机服务框架上看 性能提升的思考方向 可用性提升的思考方向 扩展性提升的思考方向 文章简介 先从整体&#xff0c;体系认识&#xff0c;理解高并发的策略&#xff0c;方…

深入理解JS的执行上下文、词法作用域和闭包(上)

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

ARM Cortex-X5 传言表现不佳,高功率浪涌和低多核分数影响即将推出的核心设计

ARM 的新 Cortex-X5 设计似乎遇到了问题&#xff0c;有新的传言称&#xff0c;超级核心在提高时钟速度时会经历严重的高功耗&#xff0c;并且当最大功率限制降低时&#xff0c;多核性能会下降。虽然这对高通来说可能不是问题&#xff0c;因为据说其 Snapdragon 8 Gen 4 采用定制…

华为HCIP Datacom H12-831 卷24

多选题 1、如图所示&#xff0c;某园区部署OSPF实现网络互通&#xff0c;其中Area1部署为NSSA区域。某工程师为了实现R1访问R4的环回口地址&#xff0c;在R4的OSPF进程中引入直连路由。以下关于该场景的描述,错误的有哪些项? A、在R4引入直连路由后&#xff0c;R1通过转换后的…

服务区智慧公厕

在如今追求智能化、便捷化的社会背景下&#xff0c;高速公路服务区智慧公厕正成为人们关注的焦点。作为高速公路上的必要设施&#xff0c;公厕的提升已经不再局限于简单的清洁卫生&#xff0c;而是更多地涉及到智能化、舒适度和用户体验。本文以智慧公厕源头厂家广州中期科技有…

华为---RSTP(三)---P/A机制及RSTP的生成树形成过程

目录 1. P/A机制简介 1.1 P/A机制的作用 1.2 P/A协商的前提条件 1.3 RSTP选举思路 2. P/A协商过程 3. 举例说明RSTP的生成树形成过程 3.1 示例环境要求 3.2 RSTP的生成树形成过程 3.2.1 SW和SW1之间链路上抓包分析 3.2.2 SW和SW2之间链路上抓包分析 3.2.3 SW1和SW2之…

CSS重点知识整理1

目录 1 平面位移 1.1 基本使用 1.2 单独方向的位移 1.3 使用平面位移实现绝对位置居中 2 平面旋转 2.1 基本使用 2.2 圆点转换 2.3 多重转换 3 平面缩放 3.1 基本使用 3.2 渐变的使用 4 空间转换 4.1 空间位移 4.1.1 基本使用 4.1.2 透视 4.2 空间旋转 4.3 立…

Type-C连接器笔记

一、Type-C的介绍 Type-C是一种全新的USB接口形式&#xff0c;由USB Implementers Forum&#xff08;USB-IF&#xff09;制定&#xff0c;并在2014年获得苹果、谷歌、英特尔、微软等厂商支持后开始普及。它是一种通用串行总线&#xff08;USB&#xff09;的硬件接口规范&#x…

Stable Diffusion 3 发布及其重大改进

1. 引言 就在 OpenAI 发布可以生成令人瞠目的视频的 Sora 和谷歌披露支持多达 150 万个Token上下文的 Gemini 1.5 的几天后&#xff0c;Stability AI 最近展示了 Stable Diffusion 3 的预览版。 闲话少说&#xff0c;我们快来看看吧&#xff01; 2. 什么是Stable Diffusion…

React18源码: Fiber树中的全局状态与双缓冲

Fiber树构造 在React运行时中&#xff0c;fiber树构造位于 react-reconciler 包在正式解读 fiber 树构造之前&#xff0c;再次回顾一下renconciler的4个阶段 1.输入阶段&#xff1a;衔接react-dom包&#xff0c;承接fiber更新请求2.注册调度任务&#xff1a;与调度中心(schedu…

JavaScript+PHP实现视频文件分片上传

摘要 视频文件分片上传&#xff0c;整体思路是利用JavaScript将文件切片&#xff0c;然后循环调用上传接口 upload.php 将切片上传到服务器。这样将由原来的一个大文件上传变为多个小文件同时上传&#xff0c;节省了上传时间&#xff0c;这就是文件分片上传的其中一个好处。 上…

STL容器之list

​ 1.封装除了对数据的保护、更好地管理数据之外&#xff0c;还有实现了对上层的统一&#xff1b; ​ 2.类模板参数的不同&#xff0c;一方面是为了实例化出来不同的类&#xff0c;另一方面是为了实现类的成员函数的不同&#xff1b; 一、认识list ​ 1.list是一种带头双向循…

Qt的QFileSystemModel与QTreeView、QTableView、QListView的组合使用

1.相关描述 QFileSystemModel与QTreeView、QTableView、QListView的组合&#xff0c;当QTreeView点击发生改变&#xff0c;QTableView和QListView也会发生变化 2.相关界面 3.相关代码 mainwindow.cpp #include "mainwindow.h" #include "ui_mainwindow.h"…

Python is not set from command line or npm configuration 报错解决

问题 在 npm install 的过程中提示 Python is not set from command line or npm configuration 的报错&#xff0c;相信不少朋友都遇到过&#xff0c;出现这个问题的原因是缺少 python 环境所导致的。 解决方法 1、安装 python 官网&#xff1a;https://www.python.org/dow…

[AutoSar]BSW_Com02 PDU详解

目录 关键词平台说明缩写对照表一、PDU的定义和分类1.1定义1.2 分类 缩写对照表 1 关键词 嵌入式、C语言、autosar、OS、BSW 平台说明 项目ValueOSautosar OSautosar厂商vector &#xff0c;芯片厂商TI 英飞凌编程语言C&#xff0c;C编译器HighTec (GCC) >>>>&g…

逆变器基础认知

引言 这段时间发现有些行业还是比较有意思的&#xff0c;而且有东西可学。 电源&#xff1a;LLC、PFC 逆变&#xff1a;UPS、PCS 电机&#xff1a;BLDC&#xff08;FOC&#xff09;、PMSM 电池&#xff1a;电车BMS、储能 所以会写几篇文章来入门&#xff0c;一是做笔记总结&am…

docker打包当前dinky项目

以下是我的打包过程&#xff0c;大家可以借鉴。我也是第一次慢慢摸索&#xff0c;打包一个公共项目&#xff0c;自己上传。 如果嫌麻烦&#xff0c;可以直接使用我的镜像&#xff0c;直接跳到拉取镜像&#xff01; <可以在任何地方的服务器进行拉取> docker打包当前din…

1_怎么看原理图之GPIO和门电路笔记

一、GPIO类 如下图&#xff1a;芯片输出高电平/3.3V&#xff0c;LED亮&#xff1b;当芯片输出低电平&#xff0c;则LED暗 如下图&#xff1a;输入引脚&#xff0c;当开关闭合&#xff0c;则输入为低电平/0V&#xff0c;当开关打开&#xff0c;则输入为高电平/3.3V 现在的引脚都…

一个更好的IP工具箱MyIP

什么是 MyIP &#xff1f; MyIP 是一个完全开源的 IP 信息查看器&#xff0c;可以轻松检查你的 IP&#xff0c;IP 地理位置&#xff0c;检查 DNS 泄漏&#xff0c;检查 WebRTC 连接&#xff0c;速度测试&#xff0c;ping 测试&#xff0c;MTR 测试&#xff0c;检查网站可用性等…