Leetcode第451场周赛分析总结

article/2025/6/15 15:23:28

在这里插入图片描述

题目链接

竞赛 - 力扣(LeetCode)全球极客挚爱的技术成长平台

题目解析

A. 3560. 木材运输的最小成本

AC代码

class Solution {
public:long long minCuttingCost(int n, int m, int k) {if (n > m) swap(n, m);  // n <= m;using ll = long long;ll ans = 0;if (m > k) {ans = static_cast<ll>(k) * (m - k);}return ans;}
};

思路分析

看完题目后发现,只有三辆车,题目保证有解,意味着最多只有一根木棍的长度会大于k从而被切割。接下来问题转换为,给定一根长度为n>k的木棍,将其切割为x+y=n两部分,求z=x*y的最小值。我记得这是初中常见的一个约束,最大值出现在x=y=n/2的位置,最小值出现在两端。实际上z是x的一个二次函数,在其作用域内先增加后减少。

x的最大值是k,那么z的最小值就是k*(n-k)。

可惜在实现的时候没注意乘积会导致爆long long。其实返回值是long long就应该注意到的,不太应该。

灵神用Python代码一行就搞定了。Python的int操作起来是更方便一些。在算法竞赛有时会遇到一些大数运算(超过long long范围的运算),如果用C++需要手动模拟实现,用Python就方便很多。

Python的int类型可以处理任意精度的整数,理论上没有固定的大小限制,仅受限于计算机的可用内存(RAM)。

B. 3561.移除相邻字符

AC代码

class Solution {bool aux(char x, char y) {int diff = abs(x - y);return diff == 1 || diff == 25;}
public:string resultingString(string s) {string stk;for (auto c : s) {if (stk.empty()) {stk.push_back(c);} else {if (aux(stk.back(), c)) {stk.pop_back();} else {stk.push_back(c);}}}return stk;}
};

思路分析

注意到对于每次消除,至多影响前面的一个元素。每次都移除最左边的字符对,模拟了一下发现类似栈的性质,用栈模拟。

灵神的代码是先统一入栈,再考虑能否消除,在逻辑和实现上更简洁一些。

C. 3562. 折扣价交易股票的最大利润

AC代码

class Solution {
public:int maxProfit(int n, vector<int>& present, vector<int>& future, vector<vector<int>>& hierarchy, int budget) {vector<vector<int>> graph(n);for (auto &edge : hierarchy) {int u = edge[0] - 1, v = edge[1] - 1;graph[u].push_back(v);}function<vector<vector<int>>(int)> dfs;dfs = [&](int u) -> vector<vector<int>> {vector f(budget + 1, vector<int>(2, 0));vector g = f;for (int v : graph[u]) {auto fv = dfs(v);for (int b = budget; b >= 0; b--) {for (int bv = 0; bv <= b; bv++) {for (int k = 0; k < 2; k++) {g[b][k] = max(g[b][k], g[b - bv][k] + fv[bv][k]);}}}}for (int b = 0; b <= budget; b++) {for (int k = 0; k < 2; k++) {int bu = present[u] / (k + 1);if (bu <= b) {f[b][k] = max(g[b][0], g[b - bu][1] + future[u] - bu);} else {f[b][k] = g[b][0];}}}return f;};return dfs(0)[budget][0];}
};

思路分析

比赛时想到如果员工的关系是一个链表,那我可以类似背包问题进行处理,对于每由于每个员工只影响自己的下属(不会影响领导),所以有无后效性。需要最大化收益,所以有最优子结构。

每个员工有两个状态:

  • 可以使用的最大费用 b b b
  • 领导是否购买股票 k k k:0表示不买,1表示买

维护每个员工 u u u在给定状态 ( b , k ) (b, k) (b,k)下他和下属可以获得的最大收益 f f f v v v表示他的下属, c k c_k ck表示在领导买股票状态为 k k k的情况下购买股票的费用, p k p_k pk表示购买股票的收益。

f u ( b , k ) = m a x { f v ( b , 0 ) , f v ( b − c k , 1 ) + p k } f_u(b,k)= max\{f_v(b,0), f_v(b-c_k, 1)+p_k\} fu(b,k)=max{fv(b,0),fv(bck,1)+pk}

然后就可以进行状态转移。可是面对一个树结构,如果某员工决定给 t t t个下属 b b b费用让他们买股票,每个下属应该用多少费用才能获得最大收益呢?感觉得再需要一个回溯去搜索,简单想了一下会超时。

在认真听了灵神的讲解后,发现自己对背包问题的理解还是太浅显。

现在让我们专心考虑这个子问题,我们可以先得到每个下属在所有状态下的收益 f v ( b , k ) f_{v}(b,k) fv(b,k)(因为是在DP中),那对于某员工有 b b b费用的情况下,我们考虑前 i i i下属消耗多少费用才能获得最大收益 g i ( b , k ) g_i(b,k) gi(b,k)

之所以考虑前 i i i个是因为员工之间的选择除了消耗费用没有额外的影响,因此无后效性,求最大收益所以有最优子结构。我们发现,员工对他们下属的费用选择形成了一个0-1背包问题,不过与普通背包问题不同的是,每个物品的价格和收益不是固定的,而是一组。

现在问题转换为,对于某个员工,已经知道前 i − 1 i-1 i1个下属可以获得的最大收益 g i − 1 ( b , k ) g_{i-1}(b,k) gi1(b,k),对第 i i i个员工,应该消耗多少费用才能使得 g i ( b , k ) g_i(b,k) gi(b,k)最大,而这是一个贪心问题:

g i ( b , k ) = max ⁡ 0 ≤ b v ≤ b g i − 1 ( b − b v , k ) + f v i ( b v , k ) g_i(b,k)=\operatorname* {max}_{0\le b_v\le b} g_{i-1}(b-b_v,k)+f_{v_i}(b_v,k) gi(b,k)=0bvbmaxgi1(bbv,k)+fvi(bv,k)

在算到所有的 g ( b , k ) g(b,k) g(b,k)后,我们就知道了给所有下属b费用可以得到的最大收益,此时状态转移变成了:

f u ( b , k ) = m a x { g v ( b , 0 ) , g ( b − c k , 1 ) + p k } f_u(b,k)= max\{g_v(b,0), g(b-c_k, 1)+p_k\} fu(b,k)=max{gv(b,0),g(bck,1)+pk}

最后的问题在大的框架上是一个树型DP,每个节点上叶子到节点的状态转移是一个0-1背包问题,在这个0-1背包问题每个物体的选择上又是一个贪心问题。

经过一段时间的理解我才梳理出整个思路,最后的代码实现使用了0-1背包的滚动数组优化。自己的思维深度还是不够,同时也应该梳理思考的顺序,把已知、转换过程都用纸笔记录下来,可以帮助自己固定思维的结果,否则想着想着都糊涂了,人类的能力真是有局限的啊(迪奥笑)。

D. 3563. 移除相邻字符后字典序最小的字符串

AC代码

class Solution {static bool is_pair(char a, char b) {int diff = abs(a - b);return diff == 1 || diff == 25;}
public:string lexicographicallySmallestString(string s) {int n = s.size();vector dp2(n, vector<int>(n, 1));for (int i = 0; i < n; ++i) dp2[i][i] = 0;for (int l = 2; l <= n; ++l) {for (int i = 0; i + l - 1 < n; ++i) {int j = i + l - 1;dp2[i][j] = 0;if (is_pair(s[i], s[j])) {dp2[i][j] = dp2[i + 1][j - 1];if (dp2[i][j]) {continue;}}for (int k = i + 1; k < j; ++k) {dp2[i][j] = (dp2[i][k] && dp2[k + 1][j]);if (dp2[i][j]) {break;}}}}vector<string> dp(n + 1);for (int i = n - 1; i >= 0; --i) {auto &&ans = dp[i];ans.push_back(s[i]);ans.append(dp[i + 1]);for (int j = i + 1; j < n; ++j) {if (dp2[i][j]) {ans = min(ans, dp[j + 1]);}}}return dp[0];}
};

思路分析

比赛的时候没有看清楚题目,想当然的以为和第二题一样是从最左边删除,然后写了一通模拟,结果理所当然地过不了。在任意位置删除相邻对的情况下,显然已经不能模拟,只能考虑动态规划或者贪心。

由于求的是最小的串,所以有最优子结构。可是前面的删除似乎会影响后面的删除,这样看来是有后效性的,似乎看起来应该去思考贪心,但是贪心也没有很好的想法,起决定作用的是前面的字符,但前面的字符有可能是通过后面的字符会删除掉。

听了灵神的讲解后发现还是要沉下心去思考。我们上面觉得前面的字符可能和后面的字符配对删除所以有后效性,但是如果确定删除了就没有后效性了。尝试定义状态dp[i]为i开始的字符串删除配对后可以得到的最小字符串,考虑状态转移:

  • 如果s[i]不删除,那显然dp[i] = s[i] + dp[i + 1]

  • 关键在于s[i]如果可以删除呢,问题变成了s[i]开始多少个字符可以删掉。由于n很小,所以我们可以遍历[i, j]字符串,如果s[i, j]可以删除,dp[i]= min(dp[i], dp[j])。

    现在问题转换为,如何快速判断s[i, j]是否可以删除。灵神说可以联想到合法括号字符串(RBS),使用区间DP处理。难点在于,我联想不到,注意力薄弱。

最终问题通过区间DP处理出哪些区间可以被消除,再用线性DP算出以某个字符开始可以得到的最小字符串。

总结

对这种需要多重转换组合的问题,一旦卡住就没法继续下去。以后对于每个思考的方向,物理化自己的思维过程,把卡住的地方转换成新的问题重新思考,不要卡住了就想来想去没有进展。


http://www.hkcw.cn/article/nIFYvKUJqt.shtml

相关文章

Maestro CLI云端测试以及github cl,bitrise原生cl的测试流程

昨天我们了解了maestro测试框架以及maestro studio工具以及创建我们的第一个flow&#xff0c;然后通过例子在maestro cli云端进行测试请求并且成功&#xff0c;今天我们就在我们自己的app上简单的进行三种测试流程&#xff0c;maestro cli云端测试&#xff0c;github cl集成测试…

少年跪地救人 获救者到学校感谢 深情拥抱致谢恩人

5月25日晚,在芜湖市繁昌一中东大门外,中年男子孙修义在路边昏厥。17岁高二学生骆易跪地三分钟,成功施救。5月30日下午,康复出院后的孙修义和妻子俞乃芽来到学校,向救命恩人骆易当面致谢,送上锦旗、感谢信和鲜花。见到骆易时,孙修义眼眶泛红,快步上前将少年拥入怀中,哽…

亚洲篮球冠军联赛完成抽签 小组对决揭晓

北京时间5月31日,2025年FIBA亚洲篮球冠军联赛分组抽签结果公布。浙江广厦男篮与乌兰巴托野马队及塔比亚特队同处A组。A组包括:浙江广厦(中国)、乌兰巴托野马(蒙古)、塔比亚特(伊朗);B组有宇都宫Brex队(日本)、马尼拉电气(菲律宾)、迪拜青年国民(阿联酋);C组则由…

知名黄金机构疑爆雷 有人被套超千万 黄金托管模式风险凸显

近日,浙江永坤控股有限公司(以下简称永坤黄金)出现兑付异常,引发广泛关注。多名投资者反映,无论在线上还是线下购买的黄金都无法提取或退款。永坤黄金提供线上和线下的黄金买卖服务,但大部分时间里,黄金并不在投资者手中,这种模式被称为黄金托管。业内人士指出,这种模…

广州市中心堵船了 龙舟盛景再现珠江

端午节期间,广州CBD上演了一场热闹非凡的龙舟招景仪式。5月31日上午,猎德涌上锣鼓喧天、鞭炮齐鸣,140个兄弟村社的150多条龙船汇聚于此,共庆佳节。这是猎德村近十年来规模最大的一次龙舟招景活动。河涌里舟楫相连,出现了“堵船”的盛况。河涌两岸挤满了围观的市民游客,欢…

用python绘制表格

1. 使用 tabulate 库&#xff08;终端/文本表格&#xff09; 适合在命令行或终端中快速生成简单的文本表格。 # 安装库 pip install tabulate # 示例代码 from tabulate import tabulatedata [["Alice", 28, "Engineer"],["Bob", 32, "…

【图文】VSCode配置与安装(超详细教程版)

目录 一、下载 二、安装 三、设置 四、环境配置&#xff08;随时更新&#xff09; 1.Python配置 一、下载 官网链接&#xff1a;Visual Studio Code - Code Editing. Redefined 点击“Download for Windows”&#xff0c;下载安装包后双击安装。 二、安装 双击下载好的…

【五子棋在线对战】一.前置知识的了解

前置知识的了解 前言1.Websocketpp1.1 使用Websocketpp的原因1.2 Websocket常用接口1.3 Websocket搭建服务器流程 2.JsonCpp2.1 Json 数据对象类的表示2.2序列化和反序列化的接口2.3 演示代码 3.Mysql![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/93305f423b544fc1…

数据中台(大数据平台)之主数据管理

主数据管理是为了确保主数据一致性和准确性而进行的一系列管理活动&#xff0c;包括主数据的收集、存储、分析、更新和共享等&#xff0c;旨在确保一个组织中使用的各个系统都有准确、一致的主数据。 1.主数据编码管理&#xff1a;主数据编码是主数据的唯一标识符。主数据编码…

Leetcode 1908. Nim 游戏 II

1.题目基本信息 1.1.题目描述 Alice 和 Bob 交替进行一个游戏&#xff0c;由 Alice 先手。 在游戏中&#xff0c;共有 n 堆石头。在每个玩家的回合中&#xff0c;玩家需要 选择 任一非空石头堆&#xff0c;从中移除任意 非零 数量的石头。如果不能移除任意的石头&#xff0c…

飞致云开源社区月度动态报告(2025年5月)

自2023年6月起&#xff0c;中国领先的开源软件公司飞致云以月度为单位发布《飞致云开源社区月度动态报告》&#xff0c;旨在向广大社区用户同步飞致云旗下系列开源软件的发展情况&#xff0c;以及当月主要的产品新版本发布、社区运营成果等相关信息。 飞致云开源运营数据概览&…

湖北秭归:屈原故里过端午 龙舟竞渡展非遗

5月30日,2025年屈原故里传统龙舟大赛在湖北省秭归县茅坪镇徐家冲港湾激情开赛。秭归作为屈原的故乡,也是中国龙舟运动的重要发源地之一,端午节期间赛龙舟、祭屈原的传统习俗一直延续至今。今年的比赛继续展示了“点睛、下水、游江、竞渡、抢红”等传统的龙舟仪式,追溯历史岁…

Target店铺应该如何入驻?

Target作为美国知名的零售巨头&#xff0c;其电商平台为众多商家提供了一个拓展业务、提升品牌知名度的绝佳机会。然而&#xff0c;入驻Target平台并非易事&#xff0c;需要商家满足一系列的条件并支付相应的费用。 以下是&#xff0c;明月跨境&#xff0c;总结出的详细的入驻指…

基于PyQt5 开发的Todo应用

Demo地址&#xff1a;https://gitcode.com/rmbnetlife/todo-app-pyqt.git PyQt Todo 应用 一个使用 PyQt5 开发的现代化任务管理应用&#xff0c;帮助您高效管理日常任务和待办事项。 &#x1f4cb; 应用简介 这是一个功能完整的桌面任务管理应用&#xff0c;具有直观的图形…

springboot集成websocket给前端推送消息

一般通常情况下&#xff0c;我们都是前端主动朝后端发送请求&#xff0c;那么有没有可能&#xff0c;后端主动给前端推送消息呢&#xff1f;这时候就可以借助websocket来实现。下面给出一个简单的实现样例。 首先创建一个websocketDemo工程&#xff0c;该工程的整体结构如下&a…

002医护人员排班系统技术解析:构建高效医疗人力管理平台

医护人员排班系统技术解析&#xff1a;构建高效医疗人力管理平台 在医疗行业高速发展的今天&#xff0c;科学合理的医护人员排班对保障医疗服务质量和效率至关重要。医护人员排班系统作为医疗信息化管理的重要工具&#xff0c;通过整合医院信息管理、医护信息管理、医护类型管…

CTFHub-RCE 命令注入-过滤目录分隔符

观察源代码 代码里面可以发现过滤了目录分隔符\和/ 判断是Windows还是Linux 源代码中有 ping -c 4 说明是Linux 查看有哪些文件 127.0.0.1|ls 打开flag文件 发现存在一个flag_is_here的文件夹&#xff0c;我们需要打开这个文件夹找到目标文件我们尝试分步&#xff0c;先利…

使用curlconverter网站快速生成requests请求包

在python写requests请求的时候&#xff0c;抓包后需要复制粘贴包的内容&#xff0c;然后手动修改和写代码。 最近发现一个好的网站 https://curlconverter.com/python/ 可以复制curl(bash)数据后&#xff0c;直接生成数据包&#xff0c;非常便捷。 举例说明&#xff1a; 选…

产品规格书写作结构、规范(编写指南)

一、产品规格书定义 产品规格书是一种综合性文档&#xff0c;它将产品需求、交互设计、业务流程和界面原型有机结合在一起。与传统文字为主的规格书不同&#xff0c;产品规格书通过高保真原型、动态交互和详细注释来完整表达产品功能和用户体验要求。 产品规格书是产品设计阶…

Webug4.0靶场通关笔记16- 第16关MySQL配置文件下载

目录 第16关 MySQL配置文件下载 1.打开靶场 2.源码分析 3.渗透实战 &#xff08;1&#xff09;Windows系统 &#xff08;2&#xff09;Linux系统 4、防御方法 本文通过《webug4.0靶场第16关MySQL配置文件下载》来进行渗透实战。文件下载是指 Web 应用程序在处理文件下载…