算法:外卖调度
题目
有N个餐厅和M个外卖员,每个餐厅在某个时间点会产生一个外卖订单,这些订单都有产生时间、所需送达时间和优先级。外卖员在空闲时会选择最优先的订单来配送,直到所有订单都被送达。具体规则如下: 对于每个餐厅的订单,优先级高的订单优先,其次是所需送达时间最短的订单,再次是产生时间最早的订单。外卖员在空闲时会从所有餐厅的最高优先级订单中挑选一个所需送达时间最短的订单进行配送,若所需送达时间相同则选择餐厅编号最小的订单。
输入描述
第一行三个数N、M、P,分别表示有N个餐厅,M个外卖员,P个订单随后有P行,每行有4个数字,分别是餐厅编号、产生时间、优先级和所需送达时间。
输出描述
输出P行,每行表示每个订单被送达的时间点。
示例:
输入:
2 2 4
1 1 2 5
1 4 3 2
2 2 1 4
2 5 2 1
输出:
6
8
6
7
实现思路
-
订单的排序与优先队列:
- 首先将所有订单按照产生时间进行排序。这样可以按照时间顺序逐步处理订单。
- 使用一个优先队列
pq(最大堆)来存储当前时间点可以处理的订单,并根据优先级、送达时间、餐厅编号的规则排序。
-
外卖员的空闲时间管理:
- 使用一个最小堆
delivery_boys来记录每个外卖员的空闲时间。最小堆确保我们总是优先分配订单给最早空闲的外卖员。
- 使用一个最小堆
-
模拟订单分配:
- 当前时间点为最早空闲的外卖员的空闲时间或者下一个订单的产生时间。
- 将当前时间点之前产生的所有订单加入优先队列
pq中。 - 从
pq中选择最优的订单,分配给最早空闲的外卖员,并更新外卖员的空闲时间。 - 如果
pq中没有订单,时间推进到下一个订单产生的时间。
-
更新订单送达时间:
- 外卖员选择订单后,送达时间为外卖员当前空闲时间或订单产生时间(取两者较大值)加上订单的送达时间。
- 记录每个订单的送达时间,并将外卖员的空闲时间更新为新的送达时间。
C++ 代码
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>using namespace std;struct Order {int restaurant;int start_time;int priority;int delivery_time;int index; // 记录订单的原始顺序
};// 定义优先级队列的排序规则
struct Compare {bool operator()(Order const& a, Order const& b) {if (a.priority != b.priority) return a.priority < b.priority;if (a.delivery_time != b.delivery_time) return a.delivery_time > b.delivery_time;return a.restaurant > b.restaurant;}
};int main() {int N = 2, M = 2, P = 4;vector<Order> orders(P);orders[0] = {1,1,2,5,0};orders[1] = {1,4,3,2,1};orders[2] = {2,2,1,4,2};orders[3] = {2,5,2,1,3};// 按产生时间排序sort(orders.begin(), orders.end(), [](Order const& a, Order const& b) {return a.start_time < b.start_time;});vector<int> result(P, 0);priority_queue<Order, vector<Order>, Compare> pq;// 外卖员的空闲时间,最小堆priority_queue<int, vector<int>, greater<int>> delivery_boys;// 初始化所有外卖员为空闲状态for (int i = 0; i < M; i++) {delivery_boys.push(0);}int i = 0;while (i < P || !pq.empty()) {// 当前时间为最早的外卖员空闲时间或下一个订单的产生时间int current_time = delivery_boys.top();if (i < P) {current_time = max(current_time, orders[i].start_time);}// 将当前时间之前产生的订单加入优先队列while (i < P && orders[i].start_time <= current_time) {pq.push(orders[i]);i++;}if (!pq.empty()) {// 取出最早空闲的外卖员int delivery_boy_time = delivery_boys.top();delivery_boys.pop();// 选择优先级最高的订单Order top_order = pq.top();pq.pop();// 更新订单送达时间int delivery_time = max(delivery_boy_time, top_order.start_time) + top_order.delivery_time;result[top_order.index] = delivery_time;// 更新外卖员的空闲时间delivery_boys.push(delivery_time);} else {// 如果当前没有订单可分配,推进时间到下一个订单的产生时间if (i < P) {delivery_boys.push(orders[i].start_time);}}}for (int i = 0; i < P; i++) {cout << result[i] << endl;}return 0;
}
时间复杂度
-
初始排序:
- 将订单按产生时间排序的时间复杂度为 O(PlogP)O(P \log P)O(PlogP),其中 PPP 是订单数量。
-
模拟分配过程:
- 每个订单最多进入和弹出优先队列一次,进入优先队列的时间复杂度为 O(logP)O(\log P)O(logP)。
- 外卖员的空闲时间最小堆操作(插入和弹出)的时间复杂度为 O(logM)O(\log M)O(logM),其中 MMM 是外卖员的数量。
- 总的模拟分配过程的时间复杂度为 O(PlogP+PlogM)O(P \log P + P \log M)O(PlogP+PlogM)。
综合考虑,时间复杂度为 O(PlogP+PlogM)O(P \log P + P \log M)O(PlogP+PlogM)。
空间复杂度
-
优先队列
pq和delivery_boys:- 优先队列
pq最多存储 PPP 个订单,因此空间复杂度为 O(P)O(P)O(P)。 - 最小堆
delivery_boys始终存储 MMM 个外卖员的空闲时间,因此空间复杂度为 O(M)O(M)O(M)。
- 优先队列
-
其他存储:
orders数组存储 PPP 个订单的信息,因此空间复杂度为 O(P)O(P)O(P)。result数组存储每个订单的送达时间,因此空间复杂度为 O(P)O(P)O(P)。
综合考虑,空间复杂度为 O(P+M)O(P + M)O(P+M)。
相关文章:
算法:外卖调度
题目 有N个餐厅和M个外卖员,每个餐厅在某个时间点会产生一个外卖订单,这些订单都有产生时间、所需送达时间和优先级。外卖员在空闲时会选择最优先的订单来配送,直到所有订单都被送达。具体规则如下: 对于每个餐厅的订单,优先级高…...
leetcode50. Pow(x, n),快速幂算法
leetcode50. Pow(x, n),快速幂算法 实现 pow(x, n) ,即计算 x 的整数 n 次幂函数(即,xn )。 示例 1: 输入:x 2.00000, n 10 输出:1024.00000 示例 2: 输入ÿ…...
Xinstall神器来袭,轻松搞定CPA推广渠道统计!
在数字化营销日益盛行的今天,CPA(按行动付费)推广已成为众多企业营销的重要手段。然而,随着渠道流量和获客途径的不断变化,CPA推广渠道统计的痛点也日益凸显。别担心,Xinstall来帮你解决问题! …...
011 | efinance分析豆一主连期货
👉👉👉 《玩转Python金融量化专栏》👈👈👈 订阅本专栏的可以下载对应的代码和数据集 🚀 上一篇🌟 下一篇⬅️ 010 东方财富帖子标题情绪分析012 akshare分析NYBOT棉花历史数据 ➡️豆一主连期货(通常简称“豆一”)是指中国期货市场上以大豆为标的的期货合约…...
【Python】函数入门(下)
3))* ** 注意:也遵循位置传参在前面,按关键字传参在后面。 代码示例: def func(*args,**kwargs):print(args,kwargs) 该函数中的参数会自动根据传参的方式不同(即:按位置…...
git的基本概念和使用原理
Git是一个分布式版本控制系统,用于跟踪文件的更改并协调多个开发人员之间的工作。以下是Git的基本概念和使用原理及方式: 目录 基本概念 使用原理 基本操作示例 基本概念 版本库(Repository): 版本库是Git用来保存…...
手写简化版的vue-router
vue-router作为vue全家桶之一的重要插件,有必要去深究一下,今天我们就从0到1手写一个简化版本。 开始之前,我们使用路由插件时是先进行下载路由 npm i vue-router ,然后在main.js中使用app.use导入router插件。想要手写vue-rou…...
分享一个基于uni-app的蛋糕商城订购小程序的设计与实现(源码、调试、LW、开题、PPT)
💕💕作者:计算机源码社 💕💕个人简介:本人 八年开发经验,擅长Java、Python、PHP、.NET、Node.js、Android、微信小程序、爬虫、大数据、机器学习等,大家有这一块的问题可以一起交流&…...
Python绘图入门:使用Matplotlib绘制柱状图
Python绘图入门:使用Matplotlib绘制柱状图 柱状图是一种常见的数据可视化方式,能够直观地展示不同类别之间的数据差异。在Python中,Matplotlib是一个非常强大且灵活的绘图库,它不仅能绘制简单的图表,还能创建复杂的多…...
Qt5编译qmqtt库使用MQTT协议连接华为云IOT完成数据上传与交互
一、前言 随着物联网技术的发展,越来越多的设备通过网络互相连接,形成了庞大的智能系统。这些系统能够收集、分析并响应各种数据,从而实现自动化控制和智能化管理。在这个背景下,MQTT 成为了一个广泛使用的轻量级消息传输协议,特别适用于资源受限的环境,如移动应用或远程…...
mysql速起架子
wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.21-linux-glibc2.12-x86_64.tar.xz 下载mysql tar xvJf mysql-8.0.21-linux-glibc2.12-x86_64.tar.xz 解压 mv mysql-8.0.21-linux-glibc2.12-x86_64 mysql-8.0 改名 去到bin目录 cd bin mkdir data gr…...
云动态摘要 2024-08-14
给您带来云厂商的最新动态,最新产品资讯和最新优惠更新。 最新优惠与活动 注册阿里云免费领云服务器_云服务器ECS_阿里云 阿里云 2024-08-14 云上试用新玩法,个人享300元免费额度,企业享660元免费额度,多种规格随心试 [免费体验…...
Elasticsearch 桶(Bucket)聚合详解及示例
在 Elasticsearch 中,桶(Bucket)聚合是一种强大的工具,它允许我们对数据进行分组并统计每组的数量。这种聚合类型对于理解数据的分布和进行分组统计非常有用。本文将详细介绍 Elasticsearch 的桶聚合,并提供完整的示例…...
Django基础知识
文章目录 新建Django项目helloworld关联数据库admin 新建Django项目 创建django-admin startproject project_name 运行 python manage.py runserver 创建app: python manage.py startapp app_name 目录: 配置文件 settings.py 路由配置 urls.py 项目管理 manage.p…...
使用 nginx 搭建代理服务器(正向代理 https 网站)指南
简介 正向代理 简介 在企业开发环境中,局域网内的设备通常需要通过正向代理服务器访问互联网。正向代理服务器充当中介,帮助客户端请求外部资源并返回结果。局域网内也就是俗称的内网,局域网外的互联网就是外网,在一些特殊场景内…...
深入解析亚马逊数据采集工具选择:Data API/Scrape API/Pangolin采集器
引言 在当今电商领域,亚马逊已成为全球最大的在线零售平台之一。随着竞争的加剧和市场的多样化,商家和企业不仅需要优秀的产品和服务,还需要通过深入的数据分析来制定更加精准的市场策略。因此,采集亚马逊站点数据已成为企业实现…...
探索Linux多样性:主流发行版及其应用场景
目录 引言 Debian:稳定性的标杆 Ubuntu:易用性的代表 Red Hat Enterprise Linux (RHEL):企业的首选 Fedora:创新的前沿 CentOS:开源的稳定之选 Arch Linux:高级用户的定制天堂 Gentoo:性…...
CentOS7.6 HAproxy-7层负载均衡集群——实施方案
目录 1、前期环境准备 1.准备4台主机 1. 设置主机名 2. 设置IP地址然后重启网卡 3. 关闭防火墙和selinux 4. 全部的服务器完成时间统一 二、配置haproxy(192.168.200.11)服务器 1. 安装haproxy 2. haproxy 配置中分成五部分内容 3. 配置HAproxy(192.168.2…...
升级ubuntu22.10到24.04
将所有kinetic换成noble,noble是24.04源,sed或手动改。 cd /etc/aptgrep -nr kinetic将old-releases.ubuntu.com替换成国内的地址,因为2210国内源没找到,没有了,但是现在更新到24.04,国内是有的。 apt up…...
YOLO好像也没那么难?
“学YOLO的念头是想整个游戏外挂!” 目录 基本原理 模型推理 IOU交并比 NMS非极大值抑制 模型训练 损失函数LOSS 代码实现 YOLO学习渠道 基本原理 模型推理 学习一个新的神经网络结构,作者认为整明白输入和输出是怎么回事就OK了,至于…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...
3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...
sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...
Web后端基础(基础知识)
BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。 优点:维护方便缺点:体验一般 CS架构:Client/Server,客户端/服务器架构模式。需要单独…...
API网关Kong的鉴权与限流:高并发场景下的核心实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中,API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关,Kong凭借其插件化架构…...
