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

作者推荐

【深度优先搜索】【树】【有向图】【推荐】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.hqwc.cn/news/478982.html

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

相关文章

前端|Day2:列表、表格、表单(黑马笔记)

Day2&#xff1a;列表、表格、表单 目录 Day2&#xff1a;列表、表格、表单一、列表1.无序列表2.有序列表3. 定义列表 二、表格1.基本使用2. 表格结构标签(了解)3.合并单元格 三、表单1.input 标签2.input 标签占位文本3.单选框4.上传文件5.多选框6.下拉菜单7.文本域8.label 标…

DS:循环队列的实现

创作不易&#xff0c;给个三连吧&#xff01;&#xff01; 一、前言 对于循环队列&#xff0c;博主也是源自于一道力扣的OJ题 力扣&#xff1a;循环队列的设置 后来我在网上查过&#xff0c;这个循环队列是有自己的应用场景的&#xff01;&#xff01;并不是出题者为了出题…

【数据分享】2014-2024年全国监测站点的逐时空气质量数据(15个指标\Excel\Shp格式)

空气质量的好坏反映了空气的污染程度&#xff0c;在各项涉及城市环境的研究中&#xff0c;空气质量都是一个十分重要的指标。空气质量是依据空气中污染物浓度的高低来判断的。 我们发现学者王晓磊在自己的主页里面分享了2014年5月以来的全国范围的到站点的逐时的空气质量数据&…

Java+SpringBoot:农业疾病防治新选择

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

stm32 DCMI的知识点

1.DCMI的简介 DCMI全称Digital camera interface&#xff08;数字摄像头接口&#xff09;&#xff0c;是一种可以采集摄像头数据的一种接口。此接口适用于黑白摄像头、X24 和 X5 摄像头&#xff0c;并可以假定所有预处理&#xff08;如调整大小&#xff09;都可以在该摄像头模…

初识小程序

一、小程序的页面布局 1、小程序组件&#xff08;标签&#xff09; view&#xff1a;代表块级区块 html中的div text&#xff1a;代表行内区块 html中的span 2、样式选择器 --- 类选择器、标签选择器、后代选择器 3、组成页面的4种文件类型 .wxml&#xff1a;页面结构和内容 …

Ubuntu 20.04.1 共享samba给windows 10

通过ssh登录ubuntu&#xff0c;修改/etc/下的smb配置文件&#xff0c; uidq4932hzh57415u:/work$ cat /etc/samba/smb.conf [global] security ads realm V01.NET workgroup V01 idmap uid 10000-20000 idmap gid 10000-20000 winbind enum users yes winbind enum grou…

若依不分离版本部署流程

一、分离与不分离的区别 参考博客&#xff1a;前后端分离与不分离的本质区别&#xff01;_前后端分离本质-CSDN博客 概念适用场景前后端不分离前端页面看到的效果都是由后端控制&#xff0c;由后端渲染页面或重定向适合纯网页应用前后端分离后端仅返回前端所需的数据&#xf…

MySQL--SQL解析顺序

前言&#xff1a; 一直是想知道一条SQL语句是怎么被执行的&#xff0c;它执行的顺序是怎样的&#xff0c;然后查看总结各方资料&#xff0c;就有了下面这一篇博文了。 本文将从MySQL总体架构—>查询执行流程—>语句执行顺序来探讨一下其中的知识。 一、MySQL架构总览&a…

算法沉淀——BFS 解决拓扑排序(leetcode真题剖析)

算法沉淀——BFS 解决拓扑排序 01.课程表02.课程表 II03.火星词典 Breadth-First Search (BFS) 在拓扑排序中的应用主要是用来解决有向无环图&#xff08;DAG&#xff09;的拓扑排序问题。拓扑排序是对有向图中所有节点的一种线性排序&#xff0c;使得对于每一条有向边 (u, v)&…

Qt C++春晚刘谦魔术约瑟夫环问题的模拟程序

什么是约瑟夫环问题&#xff1f; 约瑟夫问题是个有名的问题&#xff1a;N个人围成一圈&#xff0c;从第一个开始报数&#xff0c;第M个将被杀掉&#xff0c;最后剩下一个&#xff0c;其余人都将被杀掉。例如N6&#xff0c;M5&#xff0c;被杀掉的顺序是&#xff1a;5&#xff…

Java实现自动化pdf打水印小项目 使用技术pdfbox、Documents4j

文章目录 前言源码获取一、需求说明二、 调研pdf处理工具word处理工具 三、技术栈选择四、功能实现实现效果详细功能介绍详细代码实现项目目录WordUtilsMain类实现部分&#xff1a;第一部分Main类实现部分&#xff1a;第二部分Main类实现部分&#xff1a;第三部分 资料获取 前言…