当前位置: 首页 > news >正文

动态规划的“数学之魂”:从DP推演到质因数分解——巧解「只有两个键的键盘」

哈喽,各位,我是前端小L。

我们的DP之旅,已经探索了序列、矩阵、树上的各种问题,它们大多是“分析型”的——在一个给定的结构上寻找最优解。今天,我们将再次回到“构造型”DP的世界,我们的任务,是从一个A开始,通过“复制”和“粘贴”,以最快的速度,“生产”出nA

这道题,是DP与初等数论结合的绝佳典范。它将向我们展示,动态规划的递推关系,有时会惊人地揭示出问题背后隐藏的数学本质。

力扣 650. 只有两个键的键盘

https://leetcode.cn/problems/2-keys-keyboard/

题目分析:

  • 初始状态: 屏幕上有1个A

  • 操作:

    1. Copy All: 复制屏幕上所有的A到剪贴板。

    2. Paste: 将剪贴板的内容粘贴到屏幕上。

  • 目标: 得到恰好 nA,所需要的最少操作次数。

核心洞察: Paste操作的次数,取决于你上一次Copy时屏幕上有多少个A

  • 如果你上次在有 jA时按下了Copy,那么每次Paste,屏幕上的A就会增加 j 个。

  • 要从 jA变成 iA,你需要1次Copy,和 (i/j - 1)Paste。总共需要 1 + (i/j - 1) = i/j 次操作。

  • 这也意味着,j 必须是 i 的一个因数

思路一:动态规划的“正统”之路 (O(n²))

这个“因数”关系,就是我们构建DP的基石。

1. DP状态定义: dp[i] 表示:得到 iA所需要的最少操作次数。

2. 状态转移方程推导: 为了计算 dp[i],我们思考,这 iA是怎么来的? 它必然是从某个状态 dp[j]ji 的因数)通过CopyPaste得到的。 从 jAiA,需要的操作数是 i/j 次。 所以,通过这条路径得到的总操作数是 dp[j] + i/j

但是,i 可能有很多因数 j。我们应该从哪个 j 转移过来呢? 为了让 dp[i] 最小,我们必须遍历所有 i 的因数 j,然后取所有 dp[j] + i/j 结果中的最小值。

于是,我们得到了状态转移方程: dp[i] = min_{j | i, j < i} { dp[j] + i/j }

3. Base Case: dp[1] = 0。我们一开始就有1个A,不需要任何操作。

代码实现 (DP)

class Solution {
public:int minSteps(int n) {if (n == 1) return 0;vector<int> dp(n + 1);dp[1] = 0;for (int i = 2; i <= n; ++i) {dp[i] = i; // 初始化为最坏情况:从1个A复制,粘贴i-1次,共i步// 遍历 i 的所有因数 j (从大到小或从小到大都可以)for (int j = i / 2; j >= 1; --j) {if (i % j == 0) {dp[i] = min(dp[i], dp[j] + i / j);}}}return dp[n];}
};

这个解法是正确的,但效率不高。它引导我们走向了更深层次的思考。

思路二:“Aha!”时刻——DP关系揭示的数学本质

让我们仔细审视 dp[i] = dp[j] + i/j。 如果 i = a * b,那么 dp(a*b) = dp(a) + b (假设从a转移)。

现在,让我们考虑 n质因数分解。 假设 n = p1 * p2 * p3 (p1, p2, p3 都是质数)。

  • dp(n) = dp(p1 * p2 * p3)

  • 为了得到 n,我们可以先得到 p1 * p2,然后再乘以 p3

  • 那么,dp(n) = dp(p1 * p2) + p3

  • 同理,dp(p1 * p2) = dp(p1) + p2

  • dp(p1) 是多少?因为 p1 是质数,它的唯一因数是1。所以 dp(p1) = dp(1) + p1/1 = 0 + p1 = p1

把它们串起来: dp(n) = dp(p1 * p2) + p3 = (dp(p1) + p2) + p3 = p1 + p2 + p3

一个惊人的结论诞生了:得到 nA的最少操作次数,恰好等于 n 的所有质因数之和!

为什么这个策略是最优的?因为CopyPaste的操作,本质上是一种“乘法”增长。而质因数,是构成一个数的最基本的“乘法”单位。我们把 n 分解成最基本的乘法单元,然后一步步地“乘”上去,这自然就是最经济的路径。

最终解法:质因数分解 (O(sqrt(n)))

现在,问题被彻底“降维”成了一个纯粹的数学问题:求 n 的质因数之和。

算法流程:

  1. 初始化 ans = 0

  2. i = 2 开始循环,i*i <= n: a. 如果 n 能被 i 整除,说明 i 是一个质因数。 b. 我们就把 i 加到 ans 中,然后把 n 除以 i,继续检查 i 是否还是 n 的因数。

  3. 循环结束后,如果 n > 1,说明 n 本身就是一个大的质因数,把它也加到 ans 中。

代码实现 (数学解法)

class Solution {
public:int minSteps(int n) {int ans = 0;for (int i = 2; i * i <= n; ++i) {while (n % i == 0) {ans += i;n /= i;}}if (n > 1) {ans += n;}return ans;}
};

总结:DP是发现规律的“显微镜”

今天这道题,是DP学习之旅中一次极其深刻和美妙的体验。它向我们展示了:

动态规划,不仅是一种求解工具,更是一种强大的分析工具。它能像一台“显微镜”,帮助我们洞察问题内部的结构和规律,有时甚至能将一个复杂的DP问题,指引向一个更简单、更本质的数学解法。

咱们下期见~

http://www.dtcms.com/a/506848.html

相关文章:

  • Blender入门学习01
  • 网站开发word文档精品简历模板网站
  • WrenAI:企业级AI数据分析平台技术解析
  • 【Processing】椭圆眼珠鼠标跟随
  • 工业显示器在矿用挖掘机中的应用
  • 济南企业网站开发网站建设域名
  • 【深度学习计算机视觉】14:实战Kaggle比赛:狗的品种识别(ImageNet Dogs)
  • 基于k8s的Python的分布式深度学习训练平台搭建简单实践
  • 网站服务器地址在哪里看前端工程师是做网站吗
  • 基于SpringBoot的环保行为记录与社区互动平台(Vue+MySQL)
  • 洛谷 P3392 涂条纹-普及-
  • 【 柒个贰航空旅游-注册安全分析报告-无验证方式导致安全隐患】
  • CentOS 7 安装 MySQL 8
  • Java 数据类型分类
  • 定制高端网站建设设计上传网站图片不显示
  • 无人机路径规划与定位技术原理及实现详解
  • 自己做公司网站适用于手机的网站怎么建设
  • 解决前端多标签页通信:BroadcastChannel
  • [css] border 渐变
  • 前端错误监控实践:Sentry 在 Vite + Vue 项目中的配置与原理详解
  • Marin说PCB之GMSL2网络中AC电容前端控制100欧姆和不做差分100欧姆的区别?
  • Oracle 数据库 Schema 备份与导入全攻略
  • PySide6 使用搜索引擎搜索 多类实现
  • 东莞市外贸网站建设公司自己做投票的网站
  • 网站建设的基础服务器专业建站公司的业务内容
  • 【iOS】KVC 与 KVO 的基本了解与使用
  • Day66 DHT11温湿度传感器驱动开发与单总线通信协议
  • 【代码管理】在本地使用github和gitee之后,可能存在冲突,导致再次提交代码时提示Couldn‘t connect to server
  • bash:**:pip:***python: 错误的解释器: 没有那个文件或目录
  • OpenCV(十二):Mat