【图论】【堆优化的单源路径】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++**实现。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【第八天】C++异常的抛出、捕获以及标准异常库

一、异常的概述 异常&#xff1a;是指在程序运行的过程中发生的一些异常事件&#xff08;如&#xff1a;除0溢出&#xff0c;数组下标越界&#xff0c;所要 读取的文件不存在,空指针&#xff0c;内存不足&#xff0c;访问非法内存等等&#xff09;。&#xff08;异常是一个类。…

职业规划,电气工程师的岗位任职资格

电气工程技术人员主要是指精通电气施工技术&#xff0c;从事与电气产相关研发工作并能够解决实际问题&#xff0c;对相关资源进行最终统筹的人员。一般来说&#xff0c;这类人员主要从事绘制、审核和把关电气图纸的工作&#xff0c;在审核电气图纸的时候&#xff0c;会检查施工…

【Golang】Golang使用embed加载、打包静态资源文件

【Golang】Golang使用embed加载、打包静态资源文件 大家好 我是寸铁&#x1f44a; 总结了一篇Golang使用embed加载静态资源文件的文章✨ 喜欢的小伙伴可以点点关注 &#x1f49d; 前言 事情是这样的&#xff1a;前不久&#xff0c;有同学问我,golang怎么把静态资源文件打包成一…

freemarker模板引擎结合node puppeteer库实现html生成图片

效果图&#xff1a; 先看效果图&#xff0c;以下是基于freemarker模板渲染数据&#xff0c;puppeteer加载html中的js及最后图片生成&#xff1a; 背景&#xff1a; 目前为止&#xff0c;后台java根据html模板或者一个网页路径生成图片&#xff0c;都不支持flex布局及最新的c…

Spring篇----第一篇

系列文章目录 文章目录 系列文章目录前言一、不同版本的 Spring Framework 有哪些主要功能?二、什么是 Spring Framework?三、列举 Spring Framework 的优点。四、Spring Framework 有哪些不同的功能?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍…

二进制部署k8s集群之cni网络插件

目录 k8s的三种网络模式 pod内容器之间的通信 同一个node节点中pod之间通信 不同的node节点的pod之间通信 flannel网络插件 flannel的三种工作方式 VxLAN host-GW UDP Flannel udp 模式 Flannel VXLAN 模式 flannel插件的三大模式的总结 calico网络插件 k8s 组网…

高速DRAM的training

随着每一代接口(Interface)和存储(memory)的频率和速率的提高&#xff0c;信号采样以及传输变得越来越困难&#xff0c;因为数据眼(data eyes)越来越小。 为了帮助高速 I/O 握手&#xff0c;接口和存储支持越来越多的Training Modes&#xff0c;系统设计人员必须将这些Trainin…

Linux之JAVA环境配置jdkTomcatMySQL

目录 一. 安装jdk 1.1 查询是否有jdk 1.2 解压 1.3 配置环境变量 二. 安装Tomcat&#xff08;开机自启动&#xff09; 2.1 解压 2.2 启动tomcat 2.3 防火墙设置 2.4 创建启动脚本&#xff08;设置自启动&#xff0c;服务器开启即启动&#xff09; 三. MySQL安装&#xff08;…

【蓝桥杯省赛真题27】python纸张数量 中小学青少年组蓝桥杯比赛python编程省赛真题解析

目录 python纸张数量 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python纸张数量 第十二届蓝桥杯青少年组python比赛选拔赛真题 一、题目要…

前后端分离vue.js+nodejs学生考勤请假系统 _fbo36

此系统设计主要采用的是nodejs语言来进行开发&#xff0c;采用vue框架技术&#xff0c;框架分为三层&#xff0c;分别是控制层Controller&#xff0c;业务处理层Service&#xff0c;持久层dao&#xff0c;能够采用多层次管理开发&#xff0c;对于各个模块设计制作有一定的安全性…

备考2025年考研数学(三):2015-2024年考研数学真题练一练

今天&#xff0c;我们继续分享2015年-2024年的考研数学三选择题&#xff0c;随机做5道真题&#xff0c;并提供解析。看看正在备考2025年考研的你能做对几道。 考研数学和政治、英语一项&#xff0c;都是拉分大户&#xff0c;但是数学如果掌握了技巧&#xff0c;吃透了知识点的话…

科普GAI:走进生成式人工智能的世界

今天&#xff0c;我们来聊聊一个科技界热门话题——GAI&#xff08;Generative Artificial Intelligence&#xff09;&#xff0c;也就是生成式人工智能。顾名思义&#xff0c;GAI是指那些能够自己“生”出新内容的人工智能系统&#xff0c;就像一位永不停歇的创新者&#xff0…

vue3+js 实现记住密码功能

常见的几种实现方式 1 基于spring security 的remember me 功能 ​​​​​​​ localStorage 除非主动清除localStorage 里的信息 &#xff0c;不然永远存在&#xff0c;关闭浏览器之后下次启动仍然存在 存放数据大小一般为5M 不与服务器进行交互通信 cookies 可以…

Docker容器实战

"爱在&#xff0c;地图上&#xff0c;剥落~" Mysql 容器化安装 我们可以在 docker hub上&#xff0c;进入mysql的镜像仓库&#xff0c;找到适合的版本。 直接拉取镜像: docker pull mysql:latest 我们知道 msyql 的默认端口是 3306 &#xff0c;而且有密码&#x…

黑马JavaWeb开发跟学(一)Web前端开发HTML、CSS基础

黑马JavaWeb开发一.Web前端开发HTML、CSS基础 引子、Web开发介绍传统路线本课程全新路线本课程适用人群课程收获一、什么是web开发二、网站的工作流程三、网站的开发模式四、网站的开发技术 前端开发基础一、前端开发二、HTML & CSS2.1 HTML快速入门2.1.1 操作第一步第二步…

蓝桥杯14届计算思维国赛U8组包含真题和答案

十四届蓝桥杯国赛考试计算思维 U8 组 答案在底部 第一题 以下选项中,( )是由美国计算机协会设立,对在计算机领域内作出重要贡献的个人授予的奖项 。A.图灵奖 C.菲尔兹奖 B.诺贝尔奖 D.普利策奖 第二题 希希去吃寿司。餐台上摆出了许多食物,可供大家自选。如下图所示。 …

2_怎么看原理图之协议类接口之UART笔记

通信双方先约定通信速率&#xff0c;如波特率115200 一开始时&#xff0c;2440这边维持高电平 1> 开始发送时&#xff0c;由2440将&#xff08;RxD0&#xff09;高电平拉低&#xff0c;并持续一个T的时间&#xff08;为了让PC机可以反应过来&#xff09;&#xff0c;T1/波…

高级语言期末2011级A卷

1.编写函数&#xff0c;判定正整数m和n&#xff08;均至少为2&#xff09;是否满足&#xff1a;数m为数n可分解的最小质因数&#xff08;数n可分解的最小质因数为整除n的最小质数&#xff09; 提示&#xff1a;判定m为质数且m是n的最小因数 #include <stdio.h> #include…

信息安全计划:它是什么、为什么需要一个以及如何开始

每个组织都需要一个信息安全计划&#xff0c;因为数据已成为世界上最有价值的商品。与所有珍贵的东西一样&#xff0c;数据受到管理机构的严格监管&#xff0c;并且受到每个人&#xff08;包括骗子&#xff09;的觊觎。这就是网络犯罪不断增加的原因——与日益严格的合规环境同…

神经网络系列---激活函数

文章目录 激活函数Sigmoid 激活函数Tanh激活函数ReLU激活函数Leaky ReLU激活函数Parametric ReLU激活函数 &#xff08;自适应Leaky ReLU激活函数&#xff09;ELU激活函数SeLU激活函数Softmax 激活函数Swish 激活函数Maxout激活函数Softplus激活函数 激活函数 一般来说&#xf…