【状态机dp】【 排序 】 2809使数组和小于等于 x 的最少时间

本文涉及知识点

【状态机dp】 排序

LeetCode 2809. 使数组和小于等于 x 的最少时间

给你两个长度相等下标从 0 开始的整数数组 nums1 和 nums2 。每一秒,对于所有下标 0 <= i < nums1.length ,nums1[i] 的值都增加 nums2[i] 。操作 完成后 ,你可以进行如下操作:
选择任一满足 0 <= i < nums1.length 的下标 i ,并使 nums1[i] = 0 。
同时给你一个整数 x 。
请你返回使 nums1 中所有元素之和 小于等于 x 所需要的 最少 时间,如果无法实现,那么返回 -1 。
示例 1:
输入:nums1 = [1,2,3], nums2 = [1,2,3], x = 4
输出:3
解释:
第 1 秒,我们对 i = 0 进行操作,得到 nums1 = [0,2+2,3+3] = [0,4,6] 。
第 2 秒,我们对 i = 1 进行操作,得到 nums1 = [0+1,0,6+3] = [1,0,9] 。
第 3 秒,我们对 i = 2 进行操作,得到 nums1 = [1+1,0+2,0] = [2,2,0] 。
现在 nums1 的和为 4 。不存在更少次数的操作,所以我们返回 3 。
示例 2:

输入:nums1 = [1,2,3], nums2 = [3,3,3], x = 4
输出:-1
解释:不管如何操作,nums1 的和总是会超过 x 。

提示:

1 <= nums1.length <= 103
1 <= nums1[i] <= 103
0 <= nums2[i] <= 103
nums1.length == nums2.length
0 <= x <= 106

状态机dp

sum1 = ∑ \sum nums1 sum2 = ∑ \sum nums2 n = nums1.length
sum1的最终值有两部分组成:
一,每秒增加sum2。
二,清零。减少当前nums1[i]。
性质一: 对任意i清零两次,和只清第二次减少的值一样。
性质二:没必要对任意i清零两次,删除第一次清零i。最终值减少sum2。
性质三:由于不存在重复的i,故如果n秒搞不定,则永远搞不定。
性质四:如果某个最优解清零了S = {i1,i2,i3 … \dots },那么按nums2[i]的升序清零,一定是最优解,i ∈ \in S。

解法

indexs是nums2的下标,nums[indexs[i]] 升序排序。
dp[i][j] 表示处理完indexs的前i个数,操作了j秒清0的最大值

错误想法

看题解前,最终选取了m个,已经选择了j个。

代码

核心代码

 class Solution {public:int minimumTime(vector<int>& nums1, vector<int>& nums2, int x) {const int n = nums1.size();const int sum1 = std::accumulate(nums1.begin(), nums1.end(), 0);const int sum2 = std::accumulate(nums2.begin(), nums2.end(), 0);if (sum1 <= x) { return 0; }vector<int> indexs(n);iota(indexs.begin(), indexs.end(), 0);sort(indexs.begin(), indexs.end(), [&](const int& i1, const int& i2) {return nums2[i1] < nums2[i2]; });vector<vector<int>> dp(n+1, vector<int>(n + 1,INT_MIN));//dp[i][j] 表示处理完nums的前i个数,化了j秒清0的最大值dp[0][0] = 0;for (int i = 0; i < n; i++){const int index = indexs[i];for (int j = 0; j <= n; j++) {if (INT_MIN == dp[i][j]) { continue; }dp[i + 1][j] = max(dp[i + 1][j], dp[i ][j]);//第i+1个元素不选择if (j < n) {//第i+1个元素选择dp[i + 1][j + 1] = max(dp[i + 1][j + 1], dp[i][j] + nums1[index]+nums2[index]*(j+1));}} }for (int i = 1; i <= n; i++){int iMax = 0;for (int j = 0; j <= n; j++){iMax = max(iMax, dp[j][i]);}if (sum1 + sum2 * i - iMax <= x){return i;}}return -1;}};

测试用例

template<class T>
void Assert(const T& t1, const T& 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()
{vector<int> nums1, nums2;int x;{Solution sln;nums1 = { 1, 2, 3 }, nums2 = { 1, 2, 3 }, x = 4;auto res = sln.minimumTime(nums1, nums2, x);Assert(res, 3);}}

封装了类

template<class TSave,class TRecord>
class CSingUpdateLineTree
{
public:CSingUpdateLineTree(int iEleSize):m_iEleSize(iEleSize), m_vSave(iEleSize*4){}void Update(int index, TRecord update) {Update(1, 1, m_iEleSize, index + 1, update);}void Query(int leftIndex, int leftRight) {Query(1, 1, m_iEleSize, leftIndex + 1, leftRight + 1);}void Init() {Init(1, 1, m_iEleSize);}const int m_iEleSize;
protected:void Init(int iNodeNO, int iSaveLeft, int iSaveRight){if (iSaveLeft == iSaveRight) {OnInit(m_vSave[iNodeNO], iSaveLeft);return;}const int mid = iSaveLeft + (iSaveRight - iSaveLeft) / 2;Init(iNodeNO * 2, iSaveLeft, mid);Init(iNodeNO * 2+1, mid+1, iSaveRight);OnUpdateParent(m_vSave[iNodeNO], m_vSave[iNodeNO * 2], m_vSave[iNodeNO * 2 + 1], iSaveLeft, iSaveRight);}void Query(int iNodeNO, int iSaveLeft, int iSaveRight, int iQueryLeft,int iQueryRight) {if (( iSaveLeft >= iQueryLeft) && (iSaveRight <= iQueryRight )) {OnQuery(m_vSave[iNodeNO]);return;}if (iSaveLeft == iSaveRight) {//没有子节点return;}const int mid = iSaveLeft + (iSaveRight - iSaveLeft) / 2;if (mid >= iQueryLeft) {Query(iNodeNO * 2, iSaveLeft, mid, iQueryLeft, iQueryRight);}if( mid+1 <= iQueryRight ){Query(iNodeNO * 2+1, mid+1, iSaveRight, iQueryLeft, iQueryRight);}}void Update(int iNodeNO,int iSaveLeft,int iSaveRight,int iUpdateNO, TRecord update) {if (iSaveLeft == iSaveRight){OnUpdate(m_vSave[iNodeNO], update);return;}const int mid = iSaveLeft + (iSaveRight - iSaveLeft) / 2;if (iUpdateNO <= mid) {Update(iNodeNO * 2, iSaveLeft, mid, iUpdateNO, update);}else {Update(iNodeNO * 2+1, mid+1, iSaveRight, iUpdateNO, update);}OnUpdateParent(m_vSave[iNodeNO], m_vSave[iNodeNO * 2], m_vSave[iNodeNO * 2+1],iSaveLeft,iSaveRight);}virtual void OnInit(TSave& save,int iSave)=0;virtual void OnQuery(TSave& save) = 0;virtual void OnUpdate(TSave& save, const TRecord& update) = 0;virtual void OnUpdateParent(TSave& par, const TSave& left, const TSave& r,int iSaveLeft,int iSaveRight) = 0;vector<TSave> m_vSave;
};template<class TSave = std::pair<int,int>, class TRecord = int >
class CMyLineTree : public CSingUpdateLineTree<TSave, TRecord>
{
public:CMyLineTree(const vector<int>& arr):CSingUpdateLineTree<TSave,TRecord>(arr.size()){m_arr = arr;const int iMax = *std::max_element(arr.begin(), arr.end());m_vIndexs.resize(iMax + 1);for (int i = 0; i < arr.size(); i++){m_vIndexs[arr[i]].emplace_back(i);}CSingUpdateLineTree<TSave, TRecord>::Init();}int Query(int left, int r, int threshold){m_vCan.clear();CSingUpdateLineTree<TSave, TRecord>::Query(left,r);auto [i1, i2] = Query(left, r, m_vCan);return (i2 >= threshold) ? i1 : -1;}
protected:vector<int> m_vCan;virtual void OnQuery(TSave& save) override{m_vCan.emplace_back(save.first);}virtual void OnUpdate(TSave& save, const TRecord& update) override{save = { update,1 };}virtual void OnUpdateParent(TSave& par, const TSave& left, const TSave& r, int iSaveLeft, int iSaveRight) override{vector<int> vCan = { left.first,r.first };par = Query(iSaveLeft - 1, iSaveRight - 1, vCan);}std::pair<int, int> Query(int left, int r, vector<int> vCan){for (const auto& n : vCan){if (-1 == n) {continue;}auto it1 = std::lower_bound(m_vIndexs[n].begin(), m_vIndexs[n].end(), left);auto it2 = std::upper_bound(m_vIndexs[n].begin(), m_vIndexs[n].end(), r);const int iCnt = it2 - it1;if (2 * iCnt > (r - left + 1)){return { n,iCnt };}}return { -1,0 };}vector<vector<int>> m_vIndexs;vector<int> m_arr;virtual void OnInit(TSave& save, int iSave) override{save = { m_arr[iSave - 1],1 };}
};class MajorityChecker {
public:MajorityChecker(vector<int>& arr) :m_lineTree(arr) {}int query(int left, int right, int threshold) {return m_lineTree.Query(left, right, threshold);}CMyLineTree<> m_lineTree;
};

扩展阅读

视频课程

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在【Cencos7】中安装【Nacos】并适配【PostgreSQL】数据库

在【Cencos7】中安装【Nacos-2.3.0】并适配【PostgreSQL】数据库 安装JDK wget命令下载&#xff1a; wget https://repo.huaweicloud.com/java/jdk/8u151-b12/jdk-8u151-linux-x64.tar.gz解压 tar -xzvf jdk-7u80-linux-x64.tar.gz将解压后的目录移动到/opt下 sudo mv jdk…

stable diffusion的从安装到使用

stable-diffusion&#xff0c;一个免费开源的文生图软件&#xff0c;文章主要讲怎么从源码开始安装&#xff0c;以及使用的方式 git地址&#xff1a;https://github.com/AUTOMATIC1111/stable-diffusion-webui 本人电脑环境win10&#xff0c;软件pycharm&#xff0c;需要提前…

酷开系统表现强劲,酷开科技视频化运营为大内容布局提供更好交互

最近几年&#xff0c;电视屏幕尺寸是越做越大&#xff0c;越做越薄&#xff0c;在追求电视“颜值”的同时&#xff0c;电视内置系统也成了人们选购电视的很重要的原因。酷开科技深耕电视大屏领域多年&#xff0c;酷开系统表现强劲&#xff0c;好评如潮。 有人一度认为多媒体的…

spring Cache的基本使用

一、spring Cache基本介绍&#xff08;其实是通过代理对象来进行操作的&#xff09; Spring Cache 是 Spring 框架提供的一个缓存抽象&#xff0c;它能够轻松地集成到 Spring 应用程序中&#xff0c;为方法调用的结果提供缓存支持&#xff0c;从而提高应用程序的性能和响应速度…

关于Ansible模块 ④

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 继《关于Ansible的模块 ①》、《关于Ansible的模块 ②》与《关于Ansible的模块 ③》之后&#xff0c;继续学习ansible常用模块之…

REST API实战演练之JavaScript使用Rest API

咱们前面讲了一下如何创建REST API 假期别闲着&#xff1a;REST API实战演练之创建Rest API-CSDN博客 又讲了java客户端如何使用REST API 假期别闲着&#xff1a;REST API实战演练之客户端使用Rest API-CSDN博客 接下来咱们看看JavaScript怎么使用REST API。 一、新建一个…

软件杯 深度学习人体跌倒检测 -yolo 机器视觉 opencv python

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习的人体跌倒检测算法研究与实现 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f947;学长这里给一个题目综合评分(每项满…

(源码+部署+讲解)基于Spring Boot + Vue的车位租赁系统设计与实现

前言 &#x1f497;博主介绍&#xff1a;✌专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f447;&#x1f3fb; 精彩专栏 推荐订阅&#x1f447;&#x1f3fb; 2024年Java精品实战案例《100套》 &#x1f345;文末获取源码联系&#x1f345; &#x1f31f;…

Angular 使用DomSanitizer

跨站脚本Cross-site scripting 简称XSS&#xff0c;是代码注入的一种&#xff0c;是一种网站应用程序的安全漏洞攻击。它允许恶意用户将代码注入到网页上&#xff0c;其他用户在使用网页时就会收到影响&#xff0c;这类攻击通常包含了HTML和用户端脚本语言&#xff08;JS&…

PaddleVideo:PP-TSM 视频分类

本文记录&#xff1a;使用Paddle框架训练TSM&#xff08;Temporal Shift Module&#xff09; 前提条件&#xff1a;已经安装Paddle和PadleVideo&#xff0c;具体可参考前一篇文章。 1-数据准备&#xff1a; 以UCF101为例&#xff1a;内含13320 个短视频&#xff0c;视频类别&…

ASP.NET Core 标识(Identity)框架系列(一):如何使用 ASP.NET Core 标识(Identity)框架创建用户和角色?

前言 ASP.NET Core 内置的标识&#xff08;identity&#xff09;框架&#xff0c;采用的是 RBAC&#xff08;role-based access control&#xff0c;基于角色的访问控制&#xff09;策略&#xff0c;是一个用于管理用户身份验证、授权和安全性的框架。 它提供了一套工具和库&…

AI实时换天解决方案:重塑汽车与旅行拍摄新视界

在汽车拍摄与旅行摄影领域&#xff0c;天空作为画面中的重要元素&#xff0c;往往决定着整体视觉效果的成败。美摄科技作为业界领先的AI视觉技术提供商&#xff0c;近日推出了全新的AI实时换天解决方案&#xff0c;为用户带来了前所未有的创意空间与效率提升。 传统的换天技术…

hive-3.1.2分布式搭建与hive的三种交互方式

hive-3.1.2分布式搭建&#xff1a; 一、上传解压配置环境变量 在官网或者镜像站下载驱动包 华为云镜像站地址&#xff1a; hive&#xff1a;Index of apache-local/hive/hive-3.1.2 mysql驱动包&#xff1a;Index of mysql-local/Downloads/Connector-J # 1、解压 tar -zx…

03 Php学习:echo 、 print 、EOF

echo 和 print 在 PHP 中有两个基本的输出方式&#xff1a; echo 和 print。 echo 和 print 区别: echo - 可以输出一个或多个字符串print - 只允许输出一个字符串&#xff0c;返回值总为 1 注意&#xff1a;echo 输出的速度比 print 快&#xff0c; echo 没有返回值&…

【已完成】把Win10右键改回Win7的模样

win11右键设置成原来模样的方法如下&#xff1a; 1、winr打开运行窗口&#xff0c;输入regedit&#xff0c;按下回车键确认即可打开注册表。 2、在路径中输入&#xff1a;HKEY_CURRENT_USER\SOFTWARE\CLASSES\CLSID&#xff0c;或者是依次定位点开到CLSID。 3、右键点击CLSID&…

Nginx反向代理与Tomcat实现ssm项目前后端分离部署

Nginx nginx是一款http和支持反向代理的web服务器&#xff0c;以其优越的性能被广泛使用。以下是百度百科的介绍。 Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器&#xff0c;同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔赛索耶夫为俄罗斯访问量第二的Rambler.…

基础入门-操作系统名词文件下载反弹shell防火墙绕过

目录 基础入门-操作系统&名词&文件下载&反弹shell&防火墙绕过 知识点 参考: 演示案例 基础案例 1&#xff1a;操作系统-用途&命令&权限&用户&防火墙 实用案例 1&#xff1a;文件上传下载-->解决无图形化&解决数据传输 实用案例 …

Redis中的集群(二)

节点 集群数据结构 redisClient结构和clusterLink结构的相同和不同之处 redisClient结构和clusterLink结构都有自己的套接字描述符和输入、输出缓冲区&#xff0c;这两个结构的区别在于&#xff0c;redisClient结构中的套接字和缓冲区是用于连接客户端的&#xff0c;而clust…

Visual Studio Code 终端为管理员权限

第一部 1、 Visual Studio Code 快捷方式启动选项加上管理员启动 第二步 管理员方式运行 powershell Windows 10的任务栏自带了搜索。或者开始菜单选搜索只需在搜索框中输入powershell。 在出来的搜索结果中右击Windows PowerShell&#xff0c;然后选择以管理员方式运行。 执…

网络安全:重要性与应对措施

1. 网络安全的重要性 随着互联网的普及和信息技术的快速发展&#xff0c;网络安全问题已经变得日益突出。网络攻击者可以通过各种手段窃取个人信息、破坏系统、传播病毒等&#xff0c;给个人和社会带来巨大的损失。因此&#xff0c;网络安全已经成为信息化时代的重要问题之一。…