C++前缀和算法的应用:预算内的最多机器人数目

news2024/9/24 4:26:41

本文涉及的基础知识点

C++算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频
单调双向队列
滑动窗口

题目

你有 n 个机器人,给你两个下标从 0 开始的整数数组 chargeTimes 和 runningCosts ,两者长度都为 n 。第 i 个机器人充电时间为 chargeTimes[i] 单位时间,花费 runningCosts[i] 单位时间运行。再给你一个整数 budget 。
运行 k 个机器人 总开销 是 max(chargeTimes) + k * sum(runningCosts) ,其中 max(chargeTimes) 是这 k 个机器人中最大充电时间,sum(runningCosts) 是这 k 个机器人的运行时间之和。
请你返回在 不超过 budget 的前提下,你 最多 可以 连续 运行的机器人数目为多少。
示例 1:
输入:chargeTimes = [3,6,1,3,4], runningCosts = [2,1,3,4,5], budget = 25
输出:3
解释:
可以在 budget 以内运行所有单个机器人或者连续运行 2 个机器人。
选择前 3 个机器人,可以得到答案最大值 3 。总开销是 max(3,6,1) + 3 * sum(2,1,3) = 6 + 3 * 6 = 24 ,小于 25 。
可以看出无法在 budget 以内连续运行超过 3 个机器人,所以我们返回 3 。
示例 2:
输入:chargeTimes = [11,12,19], runningCosts = [10,8,7], budget = 19
输出:0
解释:即使运行任何一个单个机器人,还是会超出 budget,所以我们返回 0 。
参数范围
chargeTimes.length == runningCosts.length == n
1 <= n <= 5 * 104
1 <= chargeTimes[i], runningCosts[i] <= 105
1 <= budget <= 1015

分析

时间复杂度

两层循环,但第二层循环,没有从头开始。所以总时间复杂度是O(n)。

滑动窗口

[left,r)如果r增加,则预算也增加。对于每个left,我们求出使[left,r]超过预算的第一个r,也就是[left,r)以left开始可以运行最多的连续机器人。这是滑动窗口的经典应用场景。

求最大充电时间(单调双向队列)

对于任意连续机器人[left,r),如果left <= x1 < x2 < r ,且chargeTimes[x1] <= chargeTimes[x2],则chargeTimes[x1]被 chargeTimes[x2]淘汰了。双向队列依qIndex次记录除淘汰外的x,那么qIndex对应的值是递减的,这意味者首元素对应的值就是最大值。qIndex会在以下情况被修改:

x2淘汰x1
增加x2
移除left,left可能已经被淘汰
[left,r]超过预算时:应该从队列移除r,不移除也可以,下个left会移除的。

注意:

r不能小于left,所以在枚举left结束时,根据需要看是否要增加r。

大致步骤

一,求前缀和。
二,枚举left。
a,枚举r。
b,更新iRet(返回值)。
c,更新双向队列。
d,如果需要更新r。
e,更新left。

枚举r退出循环

有两种情况退出循环。

方式一r=m_c,越界。[left,r)一定没超过预算,否则以方式二,退出了。
方式二[left,r]超出预算。[left,r)一定没超过预算,否则上一轮循环就退出了。
总结两种退出方式,[left,r)都是以left开始的最长连续机器人。

代码

核心代码

class Solution {
public:
int maximumRobots(vector& chargeTimes, vector& runningCosts, long long budget) {
m_c = chargeTimes.size();
vector vSum = { 0 };
for (const auto& n : runningCosts)
{
vSum.emplace_back(n + vSum.back());
}
int right = 0;
std::deque qIndexs;
int iRet = 0;
for (int left = 0; left < m_c; left++)
{
//枚举r
while (right < m_c)
{
while (qIndexs.size() && (chargeTimes[qIndexs.back()] <= chargeTimes[right]))
{
qIndexs.pop_back();
}
qIndexs.emplace_back(right);
//计算[left,right+1)的积分
const long long curCost = chargeTimes[qIndexs.front()]+(right + 1 -left)* (vSum[right+1]-vSum[left]);
if (curCost > budget)
{
break;
}
right++;
}
iRet = max(iRet, right - left);
//滑动窗口中删除left
if (qIndexs.size()&&(qIndexs.front() == left))
{
qIndexs.pop_front();
}
if (right <= left)
{
right++;
}
}
return iRet;
}
int m_c;
};

测试用例

template
void Assert(const vector& v1, const vector& v2)
{
if (v1.size() != v2.size())
{
assert(false);
return;
}
for (int i = 0; i < v1.size(); i++)
{
assert(v1[i] == v2[i]);
}
}

template
void Assert(const T& t1, const T& t2)
{
assert(t1 == t2);
}

int main()
{
Solution slu;
vector chargeTimes, runningCosts;
long long budget = 0;
int res;
chargeTimes = { 19,63,21,8,5,46,56,45,54,30,92,63,31,71,87,94,67,8,19,89,79,25 };
runningCosts = { 91,92,39,89,62,81,33,99,28,99,86,19,5,6,19,94,65,86,17,10,8,42 };
budget = 85;
res = slu.maximumRobots(chargeTimes, runningCosts, budget);
Assert(1 ,res);
chargeTimes = { 3, 6, 1, 3, 4 };
runningCosts = { 2, 1, 3, 4, 5 };
budget = 25;
res = slu.maximumRobots(chargeTimes, runningCosts, budget);
Assert(3, res);

//CConsole::Out(res);

}

2023年3月旧代码

class Solution {
public:
int maximumRobots(vector& chargeTimes, vector& runningCosts, long long budget) {
m_c = chargeTimes.size();
int left = 0;
int iRet = 0;
vector vSum(1);
std::deque qMaxIndexs;
for (int r = 0; r < m_c; r++)
{
vSum.push_back(vSum.back() + runningCosts[r]);
while (qMaxIndexs.size() && chargeTimes[r] >= chargeTimes[qMaxIndexs.back()])
{
qMaxIndexs.pop_back();
}
qMaxIndexs.push_back®;
while (qMaxIndexs.size() && ((vSum[r + 1] - vSum[left])*(r - left + 1) + chargeTimes[qMaxIndexs.front()] > budget))
{
if (qMaxIndexs.front() == left)
{
qMaxIndexs.pop_front();
}
left++;
}
iRet = max(iRet, r - left + 1);
}
return iRet;
}
int m_c;
};

2023年9月旧代码

class Solution {
public:
int maximumRobots(vector& chargeTimes, vector& runningCosts, long long budget) {
std::deque que;
int iRet = -1;
long long sum = 0;
for (int left = 0, r = 0; left < chargeTimes.size(); left++)
{
while (que.size() && (que.front() < left ))
{
que.pop_front();
}
for (; r < chargeTimes.size(); r++)
{
while (que.size() && (chargeTimes[que.back()] <= chargeTimes[r]))
{
que.pop_back();
}
que.emplace_back®;
const long long curNeed = (sum+ runningCosts[r])*(r-left+1) + chargeTimes[que.front()];
if (curNeed > budget)
{
break;
}
sum += runningCosts[r];
}
iRet = max(iRet, r - left );
//sum是runningCosts[left…r)的和
if (left != r)
{
sum -= runningCosts[left];
}
else
{
r++;
}
}
return iRet;
}
};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步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

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

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

相关文章

Maven - no main manifest attribute(SpringBoot 多模块)

问题描述 no main manifest attribute 解决方案 一个主项目下&#xff0c;多个业务模块&#xff0c;假设 starter 模块作为启动器&#xff0c;以及主项目&#xff08;project&#xff09;最外层父 pom.xml 最关键要关注这 2 个 pom.xml&#xff08;starter - pom.xml & p…

python画气泡标尺图

目录 渐变气泡图彩色气泡图 在进行实验结果分析的时候&#xff0c;气泡标尺图能非常清晰对不同的结果进行多维度的比较&#xff0c;特别是在深度学习模型大小和精度进行比较的时候非常合适使用&#xff0c;以下是几个例子。 渐变气泡图 import seaborn as sns import matplotl…

正点原子嵌入式linux驱动开发——Linux 串口RS232/485/GPS 驱动

串口是很常用的一个外设&#xff0c;在Linux下通常通过串口和其他设备或传感器进行通信&#xff0c;根据 电平的不同&#xff0c;串口分为TTL和RS232。不管是什么样的接口电平&#xff0c;其驱动程序都是一样的&#xff0c;通过外接RS485这样的芯片就可以将串口转换为RS485信号…

RZMO-A-030/210、HZMO-A-030/315电控比例压力阀控制器

RZMO-A-030/50、RZMO-A-030/210、RZMO-A-030/350、RZMO-A-030/100、RZMO-A-030/315、HZMO-A-030/50、HZMO-A-030/210、HZMO-A-030/350、HZMO-A-030/100、HZMO-A-030/315滑阀型先导式数字型比例溢流阀&#xff0c;用于压力开环控制&#xff0c;可提供板式或叠加式安装。A型&…

web - 前段三剑客

目录 前言 一. HTML 常用标签演示 图片标签 ​编辑 表格标签(重点) ​编辑 表单标签 (重点) 布局标签 其余标签 二. CSS 2.1 . css的三种引入方式 2.2 . 三大选择器 2.3 . css样式 - 浮动 2.4 . css样式 - 定位 1.static 2.absolute(绝对位置) 3.relavite(相…

Binder机制总结笔记

Binder机制总结笔记 什么是Binder&#xff1f; Binder的Android特有的IPC通信机制。Android的四大组件Activity、Service、Broadcast、ContentProvider&#xff0c;不同的App等都运行在不同的进程内&#xff0c;他们之间的通信都需要依靠Binder完成。因此Binder在整个Android系…

好用的ps滤镜插件Portraiture2024

Photoshop 是最常用到的综合性的设计工具&#xff0c;虽然PS一直在迭代升级&#xff0c;但是在细节功能上&#xff0c;PS总是无法完全满足全部所有的用户需求&#xff0c;今天coco玛奇朵推荐一个个截至目前最受欢迎的免费的PS插件&#xff0c;有了这些功能扩展的插件后PS如虎添…

OpenCV C++ 图像处理实战 ——《缺陷检测》

OpenCV C++ 图像处理实战 ——《缺陷检测》 一、结果演示二、缺陷检测算法2.1、多元模板图像2.2、训练差异模型三、图像配准3.1 功能源码3.1 功能效果四、多元模板图像4.1 功能源码五、缺陷检测5.1 功能源码六、源码测试图像下载总结一、结果演示

拓世大模型 | 立足行业所需,发力终端,缔造智能无限可能

蒸汽机的发明为人类工业革命揭开序幕&#xff0c;引领了近现代产业变革。众所周知&#xff0c;而今AI技术的革命性突破&#xff0c;站在了时代舞台的中心&#xff0c;特别是大模型的崛起&#xff0c;无疑是第四次产业革命的焦点&#xff0c;它的地位可与当年的“蒸汽机”相提并…

AndroidSDK下载及安装(Windows)

下载地址&#xff1a;https://www.androiddevtools.cn/ 找到SDK工具并下载安装 都是傻瓜式一键安装 除了注意安装路径应避免选择中文或特殊字符路径&#xff0c;应该没什么大问题。 下载安装Android SDK Android SDK Tools安装后&#xff0c;启动SDK Manager.exe&#xff1a;…

综合OA管理系统源码 OA系统源码

综合OA管理系统源码 OA系统源码 功能介绍&#xff1a; 编号&#xff1a;LQ10 一&#xff1a;系统管理 系统配置&#xff0c;功能模块&#xff0c;功能节点&#xff0c;权限角色&#xff0c;操作日志&#xff0c;备份数据&#xff0c;还原数据 二&#xff1a;基础数据 审批…

Linux-组管理和权限管理

一、组管理—基本介绍 在linux中的每个用户必须属于一个组&#xff0c;不能独立于组外。在linux中每个文件有所有者、所在组、其它组的概念。 1)所有者 2)所在组 3)其它组 4)改变用户所在的组 二、组管理—文件/目录所有者 1、查看文件或者目录的所有者和所在组的指令 所有…

文件加密,数据防泄密软件

文件加密和数据防泄密软件成为了保护信息安全的重要工具&#xff0c;它们可以有效地防止敏感数据的泄露和非法访问。 发展历史 文件加密和数据防泄密软件的发展历程可以追溯到上世纪90年代&#xff0c;当时随着互联网的普及和信息技术的不断发展&#xff0c;人们开始意识到信息…

考虑温度影响的vumat子程序在木材受火后强度分析中的应用

木结构在火灾作用下&#xff0c;木材的化学成分及物理特性会发生复杂的变化&#xff0c;导致其力学性能的改变&#xff0c;木构件承载能力降低。本文编写了考虑温度影响的木材本构vumat子程序&#xff0c;并对子程序的正确性进行了验证。 木材是一种复杂的各向异性复合材料&am…

JavaScript综合案例五

目录 一、实战案例&#xff1a;轮播图案例-完整版 代码实现 二、实战案例&#xff1a;tab栏切换 1.普通版本 代码实现 2.事件委托版本 代码实现 三、实战案例&#xff1a;表单全选反选 代码实现 四、实战案例&#xff1a;哔哩哔哩导航滑动 代码实现 五、实战案例&am…

win10安装Tensorflow(2.10-)使用最新cuda(12+),cudnn(8.9+)

# tensorflow在2.11版本后不再支持原生windows的GPU&#xff1a; https://blog.tensorflow.org/2022/09/whats-new-in-tensorflow-210.html# 1、首先&#xff0c;在windows安装好最新的GPU环境&#xff1a; https://blog.csdn.net/sinat_20174131/article/details/121781420?s…

可以实时监控屏幕的电脑监控软件

电脑已经成为了人们工作和生活不可或缺的工具。然而&#xff0c;这也带来了诸多安全问题。一些人可能会利用电脑进行不恰当的操作&#xff0c;如聊天、游戏、观看视频等&#xff0c;甚至会泄露公司的商业机密。 电脑监控软件的定义 电脑监控软件是一种用于监控电脑使用情况的软…

【CSDN 每日一练 ★★☆】【数学】字符串相乘

###【CSDN Daily Practice】【数学】字符串相乘 数学 模拟 题目 给定两个以字符串形式表示的非负整数 num1 和 num2&#xff0c;返回 num1 和 num2 的乘积&#xff0c;它们的乘积也表示为字符串形式。 示例 示例 1: 输入: num1 “2”, num2 “3” 输出: “6” 示例 2: …

【SOPHON】算能盒子SE-16的C++模型转换

目录 ONNX转MLIR指定模型的预处理过程转换结果 本文以 arcface 为例, 介绍如何编译迁移一个onnx模型至TPU平台运行。 有疑问具体可参考 TPU-MLIR ONNX转MLIR 如果模型是图片输入, 在转模型之前我们需要了解模型的预处理。如果模型用预处理后的npz文件做输入, 则不需要考虑预处…