C++前缀和算法的应用:用地毯覆盖后的最少白色砖块 原理源码测试用例

news2024/11/18 11:36:31

本文涉及的基础知识点

C++算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频

题目

给你一个下标从 0 开始的 二进制 字符串 floor ,它表示地板上砖块的颜色。
floor[i] = ‘0’ 表示地板上第 i 块砖块的颜色是 黑色 。
floor[i] = ‘1’ 表示地板上第 i 块砖块的颜色是 白色 。
同时给你 numCarpets 和 carpetLen 。你有 numCarpets 条 黑色 的地毯,每一条 黑色 的地毯长度都为 carpetLen 块砖块。请你使用这些地毯去覆盖砖块,使得未被覆盖的剩余 白色 砖块的数目 最小 。地毯相互之间可以覆盖。
请你返回没被覆盖的白色砖块的 最少 数目。
示例 1:
输入:floor = “10110101”, numCarpets = 2, carpetLen = 2
输出:2
解释:
上图展示了剩余 2 块白色砖块的方案。
没有其他方案可以使未被覆盖的白色砖块少于 2 块。
示例 2:
输入:floor = “11111”, numCarpets = 2, carpetLen = 3
输出:0
解释:
上图展示了所有白色砖块都被覆盖的一种方案。
注意,地毯相互之间可以覆盖。
参数范围:
1 <= carpetLen <= floor.length <= 1000
floor[i] 要么是 ‘0’ ,要么是 ‘1’ 。
1 <= numCarpets <= 1000

分析

原理

毛毯尽量不相互覆盖,这样可以覆盖更多的白砖。除非:毛毯放不下了。
如果能够覆盖一张毛毯,那么一定可以覆盖无限毛毯。除非 floor.length 小于carpetLen,否则一定可以覆盖。这种情况题目已经排除了。
计算最多可以盖住多少块白砖,白砖数减去盖住的白砖,就是未盖住的白砖数。
假定新毯子覆盖在[iPre,iPre + carpetLen),那么前一张毯子不一定在[iPre-carpetLen,iPre),可以更前。所以执行:
dp[i + 1] = max(dp[i], dp[i + 1]);
执行之前:dp[i]的含义是i的最后一张毯子的尾部,可以覆盖最多砖瓦数。
执行之后:dp[i]的含义是的最后一张毯子的尾部<=i,可以覆盖最多砖瓦数。

时间复杂度

O(n*n)。两层循环,第一层,枚举第i张毛毯。第二层循环,枚举上一次的覆盖位置。

步骤

一,计算白砖数量的前缀和。
二,两层循环。
## 变量解释

vSumvSum[i]表示 floor[0,i)中白砖的数量,也就是前i块砖中,白砖的数量
pre表示i块毯子,覆盖了[0,i),能盖住的最多白砖数

代码

核心代码

class Solution {
public:
int minimumWhiteTiles(string floor, int numCarpets, int carpetLen) {
//错误想法:如果盖毯子,则毯子的末端一定盖住白砖
//计算最多可以盖住多少块白砖
vector vSum = { 0 };//vSum[i]表示 floor[0,i)中白砖的数量
for (const char& ch : floor)
{
vSum.emplace_back(vSum.back() + (‘1’ == ch));
}
m_c = floor.length();
vector pre (m_c+1,0);//表示i块毯子,覆盖了[0,i),能盖住的最多白砖数
for (int i = 0; i < numCarpets; i++)
{
vector dp = pre;
for (int iPre = 0; iPre < pre.size(); iPre++)
{
const int iNew = min(m_c , iPre + carpetLen);
dp[iNew] = max(dp[iNew], pre[iPre] + (vSum[iNew]-vSum[iPre]));
}
for (int i = 0; i < m_c; i++)
{
dp[i + 1] = max(dp[i], dp[i + 1]);
}
pre.swap(dp);
}
return vSum.back() - *std::max_element(pre.begin(),pre.end());
}
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;
string floor = “10110101”;
int numCarpets = 2, carpetLen = 2;
int res;

floor = "1110111";
numCarpets = 2, carpetLen = 3;
res = slu.minimumWhiteTiles(floor, numCarpets, carpetLen);
Assert(0, res);

floor = "10110101";
numCarpets = 2, carpetLen = 2;
res = slu.minimumWhiteTiles(floor, numCarpets, carpetLen);
Assert(2, res);

floor = "11111";
numCarpets = 2, carpetLen = 3;
res = slu.minimumWhiteTiles(floor, numCarpets, carpetLen);
Assert(0, res);	


//CConsole::Out(res);

}

2023年2月旧代码

class Solution {
public:
int minimumWhiteTiles(const string floor, const int numCarpets, const int carpetLen) {
m_c = floor.length();
//dp[i][j] 已经处理了i块砖,用了j块地毯,最少为覆盖的砖数
vector<vector> dp(m_c+1, vector(numCarpets+1,INT_MAX));
dp[0][0] = 0;
for (int brick = 0; brick < m_c; brick++)
{
for (int iUseCarpets = 0; iUseCarpets <= numCarpets; iUseCarpets++)
{
const int& iValue = dp[brick][iUseCarpets];
if (INT_MAX == iValue)
{
continue;
}
//空一格
dp[brick + 1][iUseCarpets] = min(dp[brick + 1][iUseCarpets], iValue + (‘1’ == floor[brick]));
//假定不重叠,如果重叠右移到不重叠,不影响结果
if (numCarpets == iUseCarpets)
{
continue;
}
const int iNewBrick = min(brick + carpetLen, m_c);
dp[iNewBrick][iUseCarpets + 1] = min(dp[iNewBrick][iUseCarpets + 1], iValue);
}
}
return *std::min_element(dp[m_c].begin(), dp[m_c].end());
}
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

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

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

相关文章

警务可视化 玫瑰图和柱折混合图

什么时候用&#xff0c;什么时候导入echarts 完整代码&#xff1a; 搭建页面结构的代码 html <template><h2>智慧公安数字服务系统</h2><div><div class"container1"> </div> <div class"container2"></di…

【golang】Windows环境下Gin框架安装和配置

Windows环境下Gin框架安装和配置 我终于搞定了Gin框架的安装&#xff0c;花了两三个小时&#xff0c;只能说道阻且长&#xff0c;所以写下这篇记录文章 先需要修改一些变量&#xff0c;这就需要打开终端&#xff0c;为了一次奏效&#xff0c;我们直接设置全局的&#xff1a; …

vue3后台管理系统

项目创建及代码规范化开发 vue脚手架创建项目 安装vue脚手架 npm install-g vue/cli npm update -g vue/cli终端输入vue create 项目名称 即可进入模板选择 //利用vue-cli创建项目 进入模板选择 Vue CLI v5.0.8 ? Please pick a preset:Default ([Vue 3] babel, eslint)De…

LabVIEW开发基于图像处理的车牌检测系统

LabVIEW开发基于图像处理的车牌检测系统 自动车牌识别的一般步骤是图像采集、去除噪声的预处理、车牌定位、字符分割和字符识别。结果主要取决于所采集图像的质量。在不同照明条件下获得的图像具有不同的结果。在要使用的预处理技术中&#xff0c;必须将彩色图像转换为灰度&am…

【每日一题】切割后面积最大的蛋糕

文章目录 Tag题目来源题目解读解题思路方法一&#xff1a;排序 其他语言python3 写在最后 Tag 【排序】【数组】【2023-10-27】 题目来源 1465. 切割后面积最大的蛋糕 题目解读 切割后面积最大的蛋糕。 解题思路 方法一&#xff1a;排序 本题较为简单&#xff0c;找出最大…

Figma是什么软件?有哪些优势和劣势?

Figma作为目前最受欢迎的设计软件&#xff0c;在国外受到UI设计师的广泛好评。如果你还对Figma感到困惑&#xff0c;不知道它在做什么&#xff0c;那么今天将为您详细介绍Figma软件&#xff0c;以帮助您快速理解和更好地使用它。 Figma软件基本介绍 简单来说&#xff0c;Figm…

全网最全 Pandas的入门与高级教程全集,都在这里了!(PDF下载)

Pandas是Python中的重要数据分析工具&#xff0c;它提供了强大的数据结构和函数&#xff0c;用于数据清洗、探索、准备和分析。 Pandas 的DataFrame和Series使数据处理更加简单&#xff0c;可通过各种方法和工具处理大型数据集。 这个开源库支持从多种数据源加载数据&#xff0…

在线音乐网站-基于SSM实现+源码和技术实现文档

源码和文档下载地址: https://juzhendongli.store/commodity/details/6 百度云盘中存储有。

【求教】老菜鸟遇到新问题,双bug欢迎有緣人答疑

文章目录 一&#xff0c;序二&#xff0c;需求三&#xff0c;代码实现1. 代码结构2. 完整代码备份 四&#xff0c;bug1 详情1. 运行准备1. &#xff09;将 application.yml 文件active设置为test2.&#xff09;修改jdbc-mysql.properties 数据库参数设为实际值3.&#xff09;注…

CGAL 5.6 - Halfedge Data Structures

1 Introduction 半边数据结构&#xff08;缩写为 HalfedgeDS&#xff0c;模板参数缩写为 HDS&#xff09;是一种以边为中心的数据结构&#xff0c;能够维护顶点、边和面的入射信息&#xff0c;例如平面地图、多面体或其他嵌入任意维度的可定向二维曲面。每条边被分解成两个方向…

012:计算影线长度占比

怎么说呢&#xff0c;我希望得到一个数据&#xff0c;就是某个K线的影线长短。可以这样算&#xff0c;用高点和低点的差值作为分母&#xff0c;开盘价和收盘价的差值的绝对值作为分子&#xff0c;得出的值得越大&#xff0c;说明影线越长&#xff0c;影线越长&#xff0c;说明上…

【递归、搜索与回溯算法】第七节.257. 二叉树的所有路径和46. 全排列

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;递归、搜索与回溯算法 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01;&#xff01;&am…

666666666666666

标题 摘要引言1. HashMap简介&#xff1a;掌握什么是HashMap&#xff1f;&#x1f9d0;2. HashMap的操作技巧&#xff1a;从基础到高级&#x1f680;2.1 添加键值对&#xff1a;put(K key, V value) &#x1f4e5;2.2 获取值&#xff1a;get(Object key) &#x1f4e4;2.3 检查…

element ui el-table表格纵向横向滚动条去除并隐藏空白占位列

需求 当table内容列过多时&#xff0c;可通过height属性设置table高度以固定table高度、固定表头&#xff0c;使table内容可以滚动 现在需求是右侧滚动条不好看&#xff0c;需要去除滚动条&#xff0c;并隐藏滚动条所占列的位置 // ----------修改elementui表格的默认样式-…

068:mapboxGL绘制多边形,过滤获取选中的点的集合信息

第068个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中添加draw组件,绘制多边形,获取选中的点的集合信息。这里使用turf来判断点是否在多边形的范围内。通过filter方式,过滤掉未选中的点。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章…

对自动化测试的一些展望与理解

1. 需求和目标 在我开展自动化测试之前&#xff0c;其实该项目以前的测试人员也已经写了很多的接口测试用例&#xff0c;但是大多数用例处于“半瘫痪”状态&#xff0c;在CI上无人维护&#xff08;听说起初是有人维护的&#xff0c;但是后来用例多了&#xff0c;维护的人每次花…

设计模式之门面模式

前言 什么是门面模式 门面模式是一种结构型设计模式&#xff0c;它提供了一个统一的接口&#xff0c;用来访问子系统中的一群接口。它定义了一个高层接口&#xff0c;让子系统更容易使用。这种模式常用于将一个复杂的子系统封装成一个简单的接口&#xff0c;使得客户端可以方…

如何使用navicat图形化工具远程连接MariaDB数据库【cpolar内网穿透】

公网远程连接MariaDB数据库【cpolar内网穿透】 文章目录 公网远程连接MariaDB数据库【cpolar内网穿透】1. 配置MariaDB数据库1.1 安装MariaDB数据库1.2 测试局域网内远程连接 2. 内网穿透2.1 创建隧道映射2.2 测试随机地址公网远程访问3. 配置固定TCP端口地址3.1 保留一个固定的…

记 : CTF2023羊城杯 - Reverse 方向 Blast 题目复现and学习记录

文章目录 前言题目分析and复习过程exp 前言 羊城杯题目复现&#xff1a; 第一题 知识点 &#xff1a;DES算法 &#xff1a; 链接&#xff1a;Ez加密器 第二题 知识点 &#xff1a;动态调试 &#xff1a; 链接&#xff1a;CSGO 这一题的查缺补漏&#xff1a; 虚假控制流的去除…

CVE-2021-44228 Apache log4j 远程命令执行漏洞

一、漏洞原理 log4j(log for java)是由Java编写的可靠、灵活的日志框架&#xff0c;是Apache旗下的一个开源项目&#xff0c;使用Log4j&#xff0c;我们更加方便的记录了日志信息&#xff0c;它不但能控制日志输出的目的地&#xff0c;也能控制日志输出的内容格式&#xff1b;…