【动态规划】【记忆化搜索】【C++算法】664. 奇怪的打印机

作者推荐

【矩阵快速幂】封装类及测试用例及样例

本文涉及知识点

动态规划 记忆化搜索 字符串

LeetCode:664 奇怪的打印机

有台奇怪的打印机有以下两个特殊要求:
打印机每次只能打印由 同一个字符 组成的序列。
每次可以在从起始到结束的任意位置打印新字符,并且会覆盖掉原来已有的字符。
给你一个字符串 s ,你的任务是计算这个打印机打印它需要的最少打印次数。
示例 1:
输入:s = “aaabbb”
输出:2
解释:首先打印 “aaa” 然后打印 “bbb”。
示例 2:
输入:s = “aba”
输出:2
解释:首先打印 “aaa” 然后在第二个位置打印 “b” 覆盖掉原来的字符 ‘a’。
提示:
1 <= s.length <= 100
s 由小写英文字母组成

动态规划

空间复杂度😮(n2)
时间复杂度: O(n3)
小技巧: 两个挨着的字符相同可以删除一个,不影响结果。因为打印的次数不限。 此技巧使用可以稍稍提速,不使用也没问题。
动态规范的状态表示:dp[left][r]表示 让s[left,r]符合要求的最少次数。
动态规划的转移方程:必定有一次覆盖s[left],此次覆盖可以分以下两种情况:

  • 除s[i]外,没有盖其它字符或其它字符被新的印章覆盖。dp[left][r]=1 + dp[left+1][r]
  • 除s[left]外,还有字符没覆盖,假定其下标最小的为s[i],则没印章跨越s[i],故s(l,r)可以独立出来。dp[left][r] = dp[left+1,i-1]+dp[i][r]
    动态规划的初始状态: 全部为0,表示未处理。
    动态规划的填表顺序:枚举left。
    动态规划的返回值:dp[0][n-1]

代码

核心代码

class Solution {
public:int strangePrinter(string s) {		for (int i = 0; i < s.length(); i++){if ((0 == i) || (s[i] != s[i - 1])){m_s += s[i];}}	m_c = m_s.length();m_dp.assign(m_c, vector<int>(m_c));return Cal(0, m_c - 1);}int Cal(int left,int r){if (left > r){return 0;}if (0 != m_dp[left][r]){return m_dp[left][r];}int iRet = 1 + Cal(left + 1,r);for (int i = left+1 ; i <= r; i++){if (m_s[i] == m_s[left]){iRet = min(iRet,  Cal(left + 1, i - 1) + Cal(i, r));}}return m_dp[left][r] = iRet;}int m_c;string m_s;vector<vector<int>> m_dp;
};

测试用例

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 = "a";auto res = sln.strangePrinter(s);Assert(1, res);}{Solution sln;s = "aaaa";auto res = sln.strangePrinter(s);Assert(1, res);}{Solution sln;s = "aaabbb";auto res = sln.strangePrinter(s);Assert(2, res);}{Solution sln;s = "aba";auto res = sln.strangePrinter(s);Assert(2, res);}{Solution sln;s = "aabab";auto res = sln.strangePrinter(s);Assert(3, res);}{Solution sln;s = "aabacdaa";auto res = sln.strangePrinter(s);Assert(4, res);}{Solution sln;s = "acdddda";auto res = sln.strangePrinter(s);Assert(3, res);}
}

2023年一月版

class Solution {
public:
int strangePrinter(string s) {
m_c = s.length();
m_dp.assign(m_c + 1, vector(m_c,INT_MAX));
{
int len = 1;
for (int c = 0; c + len - 1 < m_c; c++)
{
m_dp[len][c] = 1;
}
}
for (int len = 2; len <= m_c; len++)
{
for (int c = 0; c + len - 1 < m_c; c++)
{
const int iEnd = c + len - 1;
if ((s[c] == s[iEnd]) || (s[iEnd] == s[iEnd - 1]))
{
m_dp[len][c] = m_dp[len - 1][c];
continue;
}
for (int iPreLen = 1; iPreLen < len; iPreLen++)
{
m_dp[len][c] = min(m_dp[len][c],m_dp[iPreLen][c] + m_dp[len - iPreLen][c + iPreLen]);
}
}
}
return m_dp[m_c][0];
}
vector<vector> m_dp;
int m_c;
};

2023年6月版

class Solution {
public:
int strangePrinter(string s) {
m_c = s.length();
memset(m_LenBegin, 0, sizeof(m_LenBegin));
for (int begin = 0; begin < m_c; begin++)
{
m_LenBegin[1][begin] = 1;
}

	for (int len = 2; len <= m_c; len++){for (int begin = 0; begin + len - 1 < m_c; begin++){const int end = begin + len - 1;if (s[begin] == s[end]){m_LenBegin[len][begin] = m_LenBegin[len - 1][begin];continue;}int iNum = INT_MAX;for (int leftLen = 1; leftLen < len; leftLen++){iNum = min(iNum, m_LenBegin[leftLen][begin] + m_LenBegin[len - leftLen][begin + leftLen]);}m_LenBegin[len][begin] = iNum;}}return m_LenBegin[m_c][0];
}
int m_c;
int m_LenBegin[100+1][100];

};

2023年7月版

class Solution {
public:
int strangePrinter(string s) {
m_c = s.length();
vector<vector> vLenBegin(m_c + 1, vector(m_c+1,1));
for (int len = 2; len <= m_c; len++)
{
for (int begin = 0; begin < m_c; begin++)
{
const int end = begin + len - 1;
if (end >= m_c)
{
continue;
}
if (s[begin] == s[end])
{
vLenBegin[len][begin] = vLenBegin[len-1][begin];
continue;
}
int iNum = INT_MAX;
for (int leftLen=1 ;leftLen < len ; leftLen++ )
{
iNum = min(vLenBegin[leftLen][begin] + vLenBegin[len - leftLen][begin + leftLen], iNum);
}
vLenBegin[len][begin] = iNum;
}
}
return vLenBegin[m_c][0];
}
int m_c;
};

2023年8月版

class Solution {
public:
int strangePrinter(string s) {
m_c = s.length();
m_vLeftRight.assign(m_c, vector(m_c,INT_MAX));
//任何印章方式都可以转成,第一次处理最右端元素
for (int len = 1; len <= m_c; len++)
{
#define END (left + len - 1)
for (int left = 0; END < m_c; left++)
{
if (1 == len)
{
m_vLeftRight[left][END] = 1;
continue;
}
for (int mid = left; mid < END; mid++)
{
m_vLeftRight[left][END] = min(m_vLeftRight[left][END], m_vLeftRight[left][mid] + m_vLeftRight[mid + 1][END] - (s[mid] == s[END]));
}
}
}
return m_vLeftRight.front().back();
}
int m_c;
vector<vector> m_vLeftRight;
};

扩展阅读

视频课程

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

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

相关文章

MacBook安装Storm与启动

MacBook安装Storm与启动 官方下载地址: https://storm.apache.org/downloads.html 官方下载 apache-storm-1.2.2.tar.gz MacBook Linux安装zookeeper 解压 tar -zxvf apache-storm-1.2.2.tar.gz先启动zookeeper cd zookeeper-3.4.12 ./bin/zkServer.sh start #查看状态 ./…

CentOS将磁盘剩余空间分配到已有分区

CentOS将磁盘剩余空间分配到已有分区 引growpartresize2fs 引 手里有台云服务&#xff0c;之前磁盘只有60G&#xff0c;在执行SQL语句时报错No space left on device. 通过df -h查看磁盘占用情况&#xff0c;确实所剩无几了 通过云服务后端控制台升级了下配置&#xff0c;将…

基于ArcGIS的晕线制作

在借助ArcGIS进行制图时&#xff0c;我们有时需要为矢量边界添加晕线&#xff0c;今天就来探索一下基于ArcGIS的晕线制作操作。 软件版本&#xff1a;ArcMap10.4.1 方法一&#xff1a;制作多环缓冲区 工具路径&#xff1a;Analysis Tools-Proximity-Mutiple Ring Buffer 思…

Vue3的使用

一 Vue3的变化 1.性能的提升 打包大小减少41% 初次渲染快55%, 更新渲染快133% 内存减少54% 2.源码的升级 使用Proxy代替defineProperty实现响应式 重写虚拟DOM的实现和Tree-Shaking 3.拥抱TypeScript Vue3可以更好的支持TypeScript 4.新的特性 Composition API&#…

入门指南:使用STM32微控制器进行ADC数据采集

使用STM32微控制器进行ADC&#xff08;模数转换器&#xff09;数据采集是嵌入式系统开发中常见的任务。本文将介绍如何通过STM32CubeMX和HAL库函数进行ADC数据采集&#xff0c;并提供相应的代码示例。 1. STM32CubeMX配置 首先&#xff0c;使用STM32CubeMX工具配置STM32微控制…

Vue3响应式系统(二)

Vue3响应式系统(一)https://blog.csdn.net/qq_55806761/article/details/135587077 六、嵌套的effect与effect栈。 什么场景会用到effect嵌套呢&#xff1f;听我娓娓道来。 就用Vue.js来说吧&#xff0c;Vue.js的渲染函数就是在effect中执行的&#xff1a; /*Foo组件*/ const…

使用mamba替换conda和anaconda配置环境安装软件

使用mamba替换miniconda和anaconda&#xff0c;原因是速度更快&#xff0c;无论是创建新环境还是激活环境 conda、mamba、anaconda都是蟒蛇的意思… 下载mambaforge wget https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh ba…

使用WAF防御网络上的隐蔽威胁之SSRF攻击

服务器端请求伪造&#xff08;SSRF&#xff09;攻击是一种常见的网络安全威胁&#xff0c;它允许攻击者诱使服务器执行恶意请求。与跨站请求伪造&#xff08;CSRF&#xff09;相比&#xff0c;SSRF攻击针对的是服务器而不是用户。了解SSRF攻击的工作原理、如何防御它&#xff0…

MongoDB-数据库文档操作(2)

任务描述 文档数据在 MongoDB 中的查询和删除。 相关知识 本文将教你掌握&#xff1a; 查询文档命令&#xff1b;删除文档命令。 查询文档 我们先插入文档到集合 stu1 &#xff1a; document([{ name:张小华, sex:男, age:20, phone:12356986594, hobbies:[打篮球,踢足球…

Ovtio不同版本下载

关注 M r . m a t e r i a l , \color{Violet} \rm Mr.material\ , Mr.material , 更 \color{red}{更} 更 多 \color{blue}{多} 多 精 \color{orange}{精} 精 彩 \color{green}{彩} 彩&#xff01; 主要专栏内容包括&#xff1a; †《LAMMPS小技巧》&#xff1a; ‾ \textbf…

Angular系列教程之观察者模式和RxJS

文章目录 引言RxJS简介RxJS中的设计模式观察者模式迭代器模式 示例代码RxJS 在 Angular 中的应用总结 引言 在Angular开发中&#xff0c;我们经常需要处理异步操作&#xff0c;例如从后端获取数据或与用户的交互。为了更好地管理这些异步操作&#xff0c;Angular中引入了RxJS&…

架构师之超时未支付的订单进行取消操作的几种解决方案

今天给大家上一盘硬菜&#xff0c;并且是支付中非常重要的一个技术解决方案&#xff0c;有这块业务的同学注意自己尝试一把哈&#xff01; 一、需求如下&#xff1a; 生成订单30分钟未支付&#xff0c;自动取消 生成订单60秒后,给用户发短信 对上述的需求&#xff0c;我们给…