欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 锐评 > 【C++贪心 分治】1717. 删除子字符串的最大得分|1867

【C++贪心 分治】1717. 删除子字符串的最大得分|1867

2024/10/25 20:27:48 来源:https://blog.csdn.net/he_zhidan/article/details/142392758  浏览:    关键词:【C++贪心 分治】1717. 删除子字符串的最大得分|1867

本文涉及知识点

贪心 分治

LeetCode1717. 删除子字符串的最大得分

给你一个字符串 s 和两个整数 x 和 y 。你可以执行下面两种操作任意次。
删除子字符串 “ab” 并得到 x 分。
比方说,从 “cabxbae” 删除 ab ,得到 “cxbae” 。
删除子字符串"ba" 并得到 y 分。
比方说,从 “cabxbae” 删除 ba ,得到 “cabxe” 。
请返回对 s 字符串执行上面操作若干次能得到的最大得分。
示例 1:
输入:s = “cdbcbbaaabab”, x = 4, y = 5
输出:19
解释:

  • 删除 “cdbcbbaaabab” 中加粗的 “ba” ,得到 s = “cdbcbbaaab” ,加 5 分。
  • 删除 “cdbcbbaaab” 中加粗的 “ab” ,得到 s = “cdbcbbaa” ,加 4 分。
  • 删除 “cdbcbbaa” 中加粗的 “ba” ,得到 s = “cdbcba” ,加 5 分。
  • 删除 “cdbcba” 中加粗的 “ba” ,得到 s = “cdbc” ,加 5 分。
    总得分为 5 + 4 + 5 + 5 = 19 。
    示例 2:
    输入:s = “aabbaaxybbaabb”, x = 5, y = 4
    输出:20
    提示:
    1 <= s.length <= 105
    1 <= x, y <= 104
    s 只包含小写英文字母。

本文涉及知识点

贪心 分治

简化情况

s只包括ab,x >= y。
性质一:n1 = min(a的数量,b的数量),无论如何操作一定能且只能删除n1次。无论那种操作都会让a和b的数量减1,故n1次后没有a或没有b。以任意方式操作n2次后,n2< n1,一定能继续操作。选择任何一个连续a,那的左右边界不会都是空,和还有b矛盾。
推论一:根据性质一,任意操作n1次后,一定剩余n - n1 × \times × 2 个a或b。
由于x>=y,求最多能消除多少次ab,令为n3次,则可以消除n1-n3次ba。
如果s[i]前面有没有消除的a,则消除ba。如果没有,则此b无法消除扔掉。
令s[i2]是b,是s[i1]是a,消除不劣于不消除。下面分四种情况证明:
如果最优解两者都没消除,消除更优。
如果s[1]被s[i3]消除,i2<i3, s[i4]和s[i2]消除,两者交换也是最优解。
如果s[1]被s[i3]消除,i2<i3, s[i2]没消除,换成s[i2]消除s[i1],效果一样。
s[i4]和s[i2]消除,s[i1]没消除。,换成s[i2]消除s[i1],效果一样。

分治

如果x < y, x和y互换,s中的a和b互换。
如果s[i]不是a或b,则拆分成s[0…i-1]和s[i+1,n-1]不影响结果。同理 将 非ab将s拆分若干个只有只包括ab的子串。
拆分规则:初始start =-1 。如果start是-1,如果s[i]是ab,则start=i;如果start不是-1,如果s[i]不是ab,则Do(start,i)。start=-1。 注意:为了不处理边界情况,在s的末尾增加’z’ 。
时间复杂度:O(n)

代码

核心代码

class Solution {public:int maximumGain(string s, int x, int y) {s += 'z';if (x < y) {swap(x, y);for (auto& ch : s) {if ('a' == ch) {ch = 'b';}else if ('b' == ch) {ch = 'a';}}}auto Do = [&](int left, int r) {int ca = 0,cab=0,cb=0;for (; left < r; left++) {if ('b' == s[left]) {if (ca > cab) {cab++;}cb++;}else {ca++;}}return x * cab + y * (min(ca, cb) - cab);};int start = -1;		int ret = 0;for (int i = 0; i < s.length(); i++) {bool b = ('a' == s[i]) || ('b' == s[i]);if (-1 == start) {if (b) { start = i; }}else {if (!b) {ret += Do(start, i);start = -1;}}}return ret;}};

单元测试

string s;int x, y;TEST_METHOD(TestMethod11){s = "cdbcbbaaabab", x = 4, y = 5;auto res = Solution().maximumGain(s, x, y);AssertEx(19, res);}TEST_METHOD(TestMethod12){s = "aabbaaxybbaabb", x = 5, y = 4;auto res = Solution().maximumGain(s, x, y);AssertEx(20, res);}

扩展阅读

我想对大家说的话
工作中遇到的问题,可以按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。
学习算法:按章节学习《喜缺全书算法册》,大量的题目和测试用例,打包下载。重视操作
有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注
闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛
失败+反思=成功 成功+反思=成功

视频课程

先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771
如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com