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

news2024/11/20 7:11:30

作者推荐

【广度优先搜索】【网格】【割点】【 推荐】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://www.coloradmin.cn/o/1469350.html

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

相关文章

MySQL--索引结构

索引-索引结构 1. 概述2. 二叉树3. B-Tree4. BTree5. Hash 1. 概述 MySQL的索引是在存储引擎层实现的&#xff0c;不同的存储引擎有不同的索引结构&#xff0c;主要包含以下几种&#xff1a; 上述是MySQL中所支持的所有的索引结构&#xff0c;下面展示不同的存储引擎对于索引…

如何连接ACL认证的Redis

点击上方蓝字关注我 应用程序连接开启了ACL认证的Redis时与原先的方式有差别&#xff0c;本文介绍几种连接开启ACL认证的Redis的Redis的方法。 对于RedisACL认证相关内容&#xff0c;可以参考历史文章&#xff1a; Redis权限管理体系(一&#xff09;&#xff1a;客户端名及用户…

计算机网络-网络互联

文章目录 网络互联网络互联方法LAN-LAN&#xff1a;网桥及其互连原理使用网桥实现LAN-LAN使用交换机扩展局域网使用路由器连接局域网 LAN-WANWAN-WAN路由选择算法非自适应路由选择算法自适应路由选择算法广播路由选择算法&#xff1a;分层路由选择算法 网络互联 网络互联是指利…

设备树详解

设备树(Device Tree)基本概念及作用 设备树(Device Tree)基本概念 在内核源码中,存在大量对板级细节信息描述的代码。这些代码充斥在/arch/arm/plat-xxx和/arch/arm/mach-xxx目录,对内核而言这些platform设备、resource、i2c_board_info、spi_board_info以及各种硬件的…

神经网络系列---分类度量

文章目录 分类度量混淆矩阵&#xff08;Confusion Matrix&#xff09;&#xff1a;二分类问题二分类代码多分类问题多分类宏平均法:多分类代码多分类微平均法&#xff1a; 准确率&#xff08;Accuracy&#xff09;&#xff1a;精确率&#xff08;Precision&#xff09;&#xf…

EasyRecovery2024免费不要钱的电脑数据恢复软件下载

EasyRecovery 2024易恢复软件在数据恢复方面的表现评价&#xff0c;EasyRecovery 2024易恢复软件在数据恢复领域享有良好的声誉&#xff0c;它提供了全面的功能&#xff0c;易于使用的界面以及可靠的数据恢复效果。以下是对该软件在数据恢复方面的详细评价&#xff1a; EasyRec…

03|JOIN关联查询优化

1. mysql关联算法 1.1 嵌套循环连接 Nested-Loop Join(NLJ) 算法 先去t2表&#xff08;驱动表&#xff09;拿一行数据,然后去t1表&#xff08;被驱动表&#xff09;做关联, 关联之后把结果集存下来最后返回. 1.2 基于块的嵌套循环连接 Block Nested-Loop Join(BNL)算法 1.把 t…

森歌深化体育营销战略,揭晓2024奥运新代言人,携手共创影响力奇迹

2024年&#xff0c;奥运龙年的春节将将过去&#xff0c;各大高端品牌便纷纷开始激烈博弈。森歌有备而来&#xff01;布局早&#xff0c;积累深&#xff0c;以其深入骨髓的体育情怀和独具匠心的品牌策略&#xff0c;成为厨电行业的佼佼者。2月27日-2月28日&#xff0c;森歌将在杭…

电子器件系列64:稳压二极管ZM4728A

C143062_稳压二极管_ZM4728A-GS08_规格书_WJ481159 稳压管可以用于信号线路的旁路&#xff0c;用于过滤高频信号&#xff1f; 这种电路叫做限幅电路 从集成电路Al的①脚输出信号通过Rl加到集成电路A2的①脚。当集成电路Al的①脚输出信号幅度没有超过VD1稳压值时&#xff0c;这…

HDL FPGA 学习 - Avlon 总线,从端口传输、主端口传输,单周期、可变周期传输

目录 1.1 Avlon 总线 定制 外设 IP 核的框架 从端口传输 从端口信号类型 从端口传输模式列举 基本单周期读写传输 固定等待周期的读写传输 可变等待周期的读写传输&#xff08;推荐&#xff09; 具有建立时间和保持时间读写传输 主端口传输 主端口信号类型 主端口传…

Day04-流程控制语句_循环结构(while,do...while,关键字continue,关键字break,循环嵌套)

文章目录 Day04- 循环结构学习目标1 while循环2 do...while循环4 循环语句的区别5 关键字continue6 关键字break7 循环嵌套案例1&#xff1a;打印5行直角三角形案例2&#xff1a;break结束当层循环 Day04- 循环结构 学习目标 理解for语句的格式和执行流程 随机数公式 理解…

MES管理系统生产过程控制的核心要素

MES&#xff08;制造执行系统&#xff09;是为优化制造业生产过程和管理而设计的软件系统&#xff0c;其核心要素包括&#xff1a; 工单管理&#xff1a;工单管理是MES系统最基本的功能之一&#xff0c;它可以跟踪和管理各种类型的工单&#xff0c;如生产工单、维修工单和质量…

IO进程线程复习:进程线程、通信

1.进程的创建 #include<myhead.h>int main(int argc, const char *argv[]) {printf("hello world\n");//父进程执行的内容int num520;//在父进程中定义的变量pid_t pidfork();//创建子进程if(pid>0){while(1){printf("我是父进程&#xff0c;num%d\n&…

【ubuntu】永久修改主机名

文章目录 1. 问题描述2. 解决方案 1. 问题描述 主机名过长&#xff08;后面的部分&#xff09; 2. 解决方案 查看主机名详情 hostnamectl修改指定主机名 hostnamectl set-hostname ubuntu2204 --static登出重进即可

【Java程序设计】【C00279】基于Springboot的智慧外贸平台(有论文)

基于Springboot的智慧外贸平台&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的智慧外贸平台 本系统分为系统功能模块、管理员功能模块、买家功能模块以及商家功能模块。 系统功能模块&#xff1a;在平台首页可以…

五篇保姆级分类诊断教程,数据特征提取+优化算法+机器学习

今天水一期&#xff0c;总结一下以前写过的几篇保姆级故障诊断。学会这几篇&#xff0c;机器学习的故障诊断你就基本合格了&#xff01; 本期内容&#xff1a;基于SABO-VMD-CNN-SVM的分类诊断。 依旧是采用经典的西储大学轴承数据。基本流程如下&#xff1a; 首先是以最小包络熵…

java spring 01 IOC源码

01.spring 中的基础是IOC

动态规划课堂1-----斐波那契数列模型

目录 动态规划的概念&#xff1a; 动态规划的解法流程&#xff1a; 题目: 第 N 个泰波那契数 解法&#xff08;动态规划&#xff09; 代码&#xff1a; 优化&#xff1a; 题目&#xff1a;最小花费爬楼梯 解法&#xff08;动态规划&#xff09; 解法1&#xff1a; 解…

mybatis中foreach批量插入并返回主键

背景 批量插入多条数据,插入成功之后每条数据中需要返回自增主键.处理办法 1.确定项目中mybatis版本,要求3.3.1以上. 查看springboot中项目版本方法: pom.xml中进入依赖(Ctrl点击进入): <dependency><groupId>org.mybatis.spring.boot</groupId><artifac…

【Flink精讲】Flink 内存管理

面临的问题 目前&#xff0c; 大数据计算引擎主要用 Java 或是基于 JVM 的编程语言实现的&#xff0c;例如 Apache Hadoop、 Apache Spark、 Apache Drill、 Apache Flink 等。 Java 语言的好处在于程序员不需要太关注底层内存资源的管理&#xff0c;但同样会面临一个问题&…