【动态规划】【字符串】2167移除所有载有违禁货物车厢所需的最少时间

news2025/1/17 21:41:08

作者推荐

【深度优先搜索】【树】【有向图】【推荐】685. 冗余连接 II

本文涉及知识点

动态规划汇总

LeetCode2167移除所有载有违禁货物车厢所需的最少时间

给你一个下标从 0 开始的二进制字符串 s ,表示一个列车车厢序列。s[i] = ‘0’ 表示第 i 节车厢 不 含违禁货物,而 s[i] = ‘1’ 表示第 i 节车厢含违禁货物。
作为列车长,你需要清理掉所有载有违禁货物的车厢。你可以不限次数执行下述三种操作中的任意一个:
从列车 左 端移除一节车厢(即移除 s[0]),用去 1 单位时间。
从列车 右 端移除一节车厢(即移除 s[s.length - 1]),用去 1 单位时间。
从列车车厢序列的 任意位置 移除一节车厢,用去 2 单位时间。
返回移除所有载有违禁货物车厢所需要的 最少 单位时间数。
注意,空的列车车厢序列视为没有车厢含违禁货物。
示例 1:
输入:s = “1100101”
输出:5
解释:
一种从序列中移除所有载有违禁货物的车厢的方法是:

  • 从左端移除一节车厢 2 次。所用时间是 2 * 1 = 2 。
  • 从右端移除一节车厢 1 次。所用时间是 1 。
  • 移除序列中间位置载有违禁货物的车厢。所用时间是 2 。
    总时间是 2 + 1 + 2 = 5 。
    一种替代方法是:
  • 从左端移除一节车厢 2 次。所用时间是 2 * 1 = 2 。
  • 从右端移除一节车厢 3 次。所用时间是 3 * 1 = 3 。
    总时间也是 2 + 3 = 5 。
    5 是移除所有载有违禁货物的车厢所需要的最少单位时间数。
    没有其他方法能够用更少的时间移除这些车厢。
    示例 2:
    输入:s = “0010”
    输出:2
    解释:
    一种从序列中移除所有载有违禁货物的车厢的方法是:
  • 从左端移除一节车厢 3 次。所用时间是 3 * 1 = 3 。
    总时间是 3.
    另一种从序列中移除所有载有违禁货物的车厢的方法是:
  • 移除序列中间位置载有违禁货物的车厢。所用时间是 2 。
    总时间是 2.
    另一种从序列中移除所有载有违禁货物的车厢的方法是:
  • 从右端移除一节车厢 2 次。所用时间是 2 * 1 = 2 。
    总时间是 2.
    2 是移除所有载有违禁货物的车厢所需要的最少单位时间数。
    没有其他方法能够用更少的时间移除这些车厢。
    提示:
    1 <= s.length <= 2 * 105
    s[i] 为 ‘0’ 或 ‘1’

动态规划

直接枚举右拆,余下的看左拆或左拆+中间拆或中间拆 那个更划算。

动态的状态表示

dp[i] 记录 s[0,i) 左拆+中间拆的最少时间。

动态规划的转移方程

s[i] = ‘0’ dp[i+1]=dp[i]
s[i]=‘1’
{ d p [ i + 1 ] = d p [ i ] + 2 中间拆 d p [ i + 1 ] = i + 1 左拆 \begin{cases} dp[i+1] = dp[i]+2 & 中间拆 \\ dp[i+1] = i+1 & 左拆 \end{cases} {dp[i+1]=dp[i]+2dp[i+1]=i+1中间拆左拆

动态规划的填表顺序

i从小到大。由于只用到dp[i]和dp[i+1] ,可以精简成两个变成pre,cur。再次精简成一个变量。

动态规划的初始值

dp[0]=0。

动态规划的返回值

dp[i] + (n-i) 的最小值。

代码

核心代码

class Solution {
public:
	int minimumTime(string s) {
		int n = s.length();
		int iRet = n;
		int cur = 0;
		for (int i = 0; i < n; i++)
		{
			if ('1' == s[i])
			{
				cur = min(i + 1, cur + 2);
			}
			iRet = min(iRet, cur + n - (i + 1));
		}
		return iRet;
	}
};

测试用例

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()
{	
	string s;
	{
		Solution sln;
		s= "1100101";
		auto res = sln.minimumTime(s);
		Assert(res,5);
	}

	{
		Solution sln;
		s = "0010";
		auto res = sln.minimumTime(s);
		Assert(res, 2);
	}

	{
		Solution sln;
		s = "00000110100111110001110111000000000";
		auto res = sln.minimumTime(s);
		Assert(res, 26);
	}
}

2023 年2月版

class Solution {
public:
int minimumTime(string s) {
vector vLeftMid,vRightMin;
{
int iAdd = 0;
int iMinLeft = 0;
for (int i = 0; i < s.length(); i++)
{
if (‘0’ == s[i])
{
continue;
}
iAdd += 2;
int iMin = min(i + 1, iMinLeft + iAdd );
vLeftMid.push_back(iMin);
iMinLeft = min(iMinLeft, iMin - iAdd);
}
}
{
int iAdd = 0;
int iMinRight = 0;
vector tmp;
for (int i = s.length() - 1; i >= 0;i–)
{
if (‘0’ == s[i])
{
continue;
}
iAdd += 2;
int iMin = min((int)s.length()-i, iMinRight + iAdd);
tmp.push_back(iMin);
iMinRight = min(iMinRight, iMin - iAdd);
}
vRightMin.assign(tmp.rbegin(), tmp.rend());
}
if (0 == vLeftMid.size())
{
return 0;
}
int iMin = min(vLeftMid.back(), vRightMin.front());
for (int i = 0; i + 1 < vLeftMid.size(); i++)
{
iMin = min(iMin, vLeftMid[i] + vRightMin[i + 1]);
}
return iMin;
}
};

2023年7月版

class Solution {
public:
int minimumTime(string s) {
m_c = s.length();
int iPreCanSub = 0;
std::queue<std::pair<int, int>> queIndexNum;// 将第index节车厢(及更左)移除节省的次数
{
int iNum = 0;//车厢数
for (int i = 0; i < s.length(); i++)
{
if (‘0’ == s[i])
{
continue;
}
iNum++;
const int iCanSub = iNum * 2 - (i + 1);//左移能够减少的次数
if (iCanSub > iPreCanSub)
{
queIndexNum.emplace(i, iCanSub);
iPreCanSub = iCanSub;
}
}
}
int iNum = 0;//车厢数
std::stack<std::pair<int, int>> staIndexNum;//将第index节车厢(及更右)移除节省的次数
{
int iPreCanSub = 0;
for (int i = s.length() - 1; i >= 0; i–)
{
if (‘0’ == s[i])
{
continue;
}
iNum++;
const int iCanSub = iNum * 2 - (s.length() - i);//右移能够减少的次数
if (iCanSub > iPreCanSub)
{
staIndexNum.emplace(i, iCanSub);
iPreCanSub = iCanSub;
}
}
}
int iMaxCanSub = iPreCanSub;
int iMaxLeftSub = 0;
while (staIndexNum.size())
{
while (queIndexNum.size() && (queIndexNum.front().first < staIndexNum.top().first))
{
iMaxLeftSub = queIndexNum.front().second;
queIndexNum.pop();
}
iMaxCanSub = max(iMaxCanSub, iMaxLeftSub + staIndexNum.top().second);
staIndexNum.pop();
}
return iNum * 2 - iMaxCanSub;
}
int m_c;
};

扩展阅读

视频课程

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

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

相关文章

自动化上位机开发C#100例:如何用面向对象的方式封装雷赛运动控制卡EtherCAT总线卡(C#代码)

自动化上位机开发C#100例:雷赛运动控制卡EtherCAT总线卡C#封装类 文章目录 LTDMC.dll下载LTDMC.cs LTDMC.dll C#调用封装下载ICard.cs 运动控制卡接口Card.cs 运动控制卡抽象类CardLTDMC.cs 雷赛运动控制卡EtherCAT总线卡实现类CardList.cs 总线卡列表封装 LTDMC.dll下载 最新…

MLP-Mixer: AN all MLP Architecture for Vision

发表于NeurIPS 2021, 由Google Research, Brain Team发表。 Mixer Architecture Introduction 当前的深度视觉结构包含融合特征(mix features)的层:(i)在一个给定的空间位置融合。(ii)在不同的空间位置&#xff0c;或者一次融合所有。在CNN中&#xff0c;(ii) 是由N x N(N &g…

golangci-lint如何关闭typecheck

https://github.com/golangci/golangci-lint/issues/2912 typecheck是go源码的校验&#xff0c;无法通过.golangci.yml配置关闭 可以直接在golangci-lint源码层面关闭typecheck

Jmeter教程-JMeter 环境安装及配置

Jmeter教程 JMeter 环境安装及配置 在使用 JMeter 之前&#xff0c;需要配置相应的环境&#xff0c;包括安装 JDK 和获取 JMeter ZIP 包。 安装JDK 1.JDK下载 示例环境为Windows11环境&#xff0c;读者应根据实际环境下载JDK的安装包。 JDK下载地址&#xff1a; Java21 下载 …

windows自带录屏指南,让视频制作更简单!

随着网络技术的发展&#xff0c;录制电脑屏幕已成为了许多用户的常见需求&#xff0c;无论是录制游戏画面、软件教程还是制作演示视频&#xff0c;一款好用的录屏工具都至关重要。windows操作系统为用户提供了多种录屏工具&#xff0c;无需额外安装软件。本篇文章将介绍windows…

Guitar Pro 8.1 Mac 2024最新下载、安装、激活、换机图文教程

Guitar Pro 8是吉他手的终极工具箱,也是阅读和编辑乐谱的领先软件。26 年来,Guitar Pro 一直在帮助世界各地的音乐家学习弹吉他、创作歌曲以及转录和编辑歌集。 Guitar Pro是一款专业的吉他制谱软件&#xff0c;现在已更新至Guitar Pro8&#xff0c;新增了支持添加音频轨道、支…

19-树-填充每个节点的下一个右侧节点指针 II

这是树的第19篇算法&#xff0c;力扣链接。 给定一个二叉树&#xff1a; struct Node {int val;Node *left;Node *right;Node *next; } 填充它的每个 next 指针&#xff0c;让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点&#xff0c;则将 next 指针设置为 NULL 。…

从入门到精通:AI绘画与修图实战指南

&#x1f482; 个人网站:【 海拥】【神级代码资源网站】【办公神器】&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交流的小伙伴&#xff0c;请点击【全栈技术交流群】 在这篇文章中&#xff0c;我们将深入探讨如何利…

JAVA高并发——人手一支笔:ThreadLocal

文章目录 1、ThreadLocal的简单使用2、ThreadLocal的实现原理3、对性能有何帮助4、线程私有的随机数发生器ThreadLocalRandom4.1、反射的高效替代方案4.2、随机数种子4.3、探针Probe的作用 除了控制资源的访问&#xff0c;我们还可以通过增加资源来保证所有对象的线程安全。比如…

2024年数学建模竞赛汇总——时间轴

美赛已过&#xff0c;好多小伙伴表示已经错过&#xff0c;不清楚什么时候报名&#xff0c;什么时候准备&#xff0c;其实每年数学建模比赛有很多个&#xff0c;各大比赛的级别、报名时间、参赛对象等要求什么呢&#xff1f;小编从竞赛说明、竞赛级别、是否允许跨校、报名费用、…

MySQL基础学习

MySQL基础 注意&#xff1a;本文的图片截图自尚硅谷MySQL笔记。 一&#xff1a;基本概述&#xff1a; 什么是数据库&#xff1a; 数据库是一种用来存储和管理数据的系统。它是一个组织化的数据集合&#xff0c;可以通过计算机系统进行访问、管理和更新。数据库可以存储各种…

【C++】vector模拟实现+迭代器失效

vector模拟实现 成员变量定义默认成员函数构造函数 迭代器范围for、对象类型匹配原则 容量操作sizeemptycapacityreserve成员变量未更新memcpy值拷贝 resize内置类型的构造函数 数据访问frontbackoperator[ ] 数据修改操作push_backpop_backswapclearinsertpos位置未更新无返回…

Atcoder ABC340 C - Divide and Divide

Divide and Divide&#xff08;分而治之&#xff09; 时间限制&#xff1a;2s 内存限制&#xff1a;1024MB 【原题地址】 所有图片源自Atcoder&#xff0c;题目译文源自脚本Atcoder Better! 点击此处跳转至原题 【问题描述】 【输入格式】 【输出格式】 【样例1】 【样例…

Unity2023.1.19没有PBR Graph?

Unity2023.1.19没有PBR Graph? 关于Unity2023.1.19没有PBR graph的说法,我没看见管方给出的答案,百度则提到了Unity2020版之后Shader Graph的“全新更新”,之前也没太注意版本的区别,以后项目尽量都留心一下。 之前文章说过,孪生智慧项目推荐使用URP渲染管线,以上的截…

基于学习的参数化查询优化方法

一、背景介绍 参数化查询是指具有相同模板&#xff0c;且只有谓词绑定参数值不同的一类查询&#xff0c;它们被广泛应用在现代数据库应用程序中。它们存在反复执行动作&#xff0c;这为其性能优化提供了契机。 然而&#xff0c;当前许多商业数据库处理参数化查询的方法仅仅只…

JavaScript编写一个倒计时

关键js代码 <script>function countdown() {var targetDate new Date("2024-02-20 12:00:00");var currentDate new Date();var timeDiff targetDate.getTime() - currentDate.getTime();var days Math.floor(timeDiff / (1000 * 60 * 60 * 24));var hours…

电商数据API接口 | 节省你的电商数据采集成本

1、将数据采集的整体成本降低55%。在电商API接口负责了整个数据采集流程后&#xff0c;这家电商公司成功节约了维护和开发上的成本。 2、电商爬虫API可以从极复杂的来源中采集数据&#xff0c;确保完整交付。在电商爬虫API的帮助下&#xff0c;该公司现在可以获取完成业务目标所…

threejs 3D标注

import { CSS3DObject } from "three/examples/jsm/renderers/CSS3DRenderer";gltfLoader.load("./model/exhibit2.glb", (gltf) >{let array ["雕像", "中药房", "浸制区", "道地沙盘","动物标本区&quo…

Java的Lock(二)

自旋锁 VS 适应性自旋锁 堵塞或者notify一个Java线程需要操作系统切换CPU状态来完成(详情请参考11408)。这种状态切换需要耗费CPU时间。如果同步代码块种的内容过于简单。状态切换消耗的时间可能比用户代码执行的时间还要长。 在许多场景中,同步资源的锁定时间很短,为了这一…

【C语言】Leetcode 88.合并两个有序数组

一、代码实现 /*** 函数名称&#xff1a;merge* * 功能描述&#xff1a;合并两个已排序的整数数组* * 参数说明&#xff1a;* nums1&#xff1a;第一个整数数组* nums1Size&#xff1a;第一个数组的大小* m&#xff1a;第一个数组中要合并的子数组的起始索引* nums2&a…