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

《序列 DP:C++ 中的“最长”套路与编辑距离》

序列 DP 就像是“找茬”“连连看”

  • LIS:在一堆乱序的数字里找最长的顺子。

  • LCS:比较两个 DNA 序列,找出共同的基因片段。

  • 编辑距离:Word 文档的“修订模式”,计算改一个单词需要多少次键盘敲击。


模块一:最长递增子序列(LIS)

1. 思路讲解

定义dp[i]:以nums[i]结尾的最长递增子序列的长度。

对于每个i,我们需要查看它之前的所有j(0 <= j < i)。

如果nums[j] < nums[i],说明nums[i]可以接在nums[j]后面形成一个新的递增序列。

状态转移:dp[i] = max(dp[i], dp[j] + 1)

2. 代码详解

cpp

class Solution { public: int lengthOfLIS(vector<int>& nums) { int n = nums.size(); if (n == 0) return 0; vector<int> dp(n, 1); // 初始化为1,因为每个元素至少可以单独成一个序列 int ans = 1; for (int i = 0; i < n; i++) { for (int j = 0; j < i; j++) { if (nums[j] < nums[i]) { dp[i] = max(dp[i], dp[j] + 1); } } ans = max(ans, dp[i]); // 更新全局最大值 } return ans; // 注意:返回的是ans,不是dp[n-1] } };
  • 易错点:答案不是dp.back(),因为最长的序列不一定以最后一个元素结尾。必须维护一个全局变量ans


模块二:最长公共子序列(LCS)

1. 思路讲解

定义dp[i][j]:字符串text1的前i个字符和text2的前j个字符的最长公共子序列长度。

  • 情况 1text1[i-1] == text2[j-1](字符相同)。

    这两个字符一定在 LCS 中,所以dp[i][j] = dp[i-1][j-1] + 1

  • 情况 2text1[i-1] != text2[j-1](字符不同)。

    这两个字符至少有一个不在 LCS 中。可能是删掉text1[i-1],也可能是删掉text2[j-1]

    所以dp[i][j] = max(dp[i-1][j], dp[i][j-1])

2. 代码详解

cpp

class Solution { public: int longestCommonSequence(string text1, string text2) { int m = text1.size(), n = text2.size(); vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0)); for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { if (text1[i - 1] == text2[j - 1]) { // 字符相同,两边都推进一格 dp[i][j] = dp[i - 1][j - 1] + 1; } else { // 字符不同,取删掉左边或删掉右边的较大值 dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); } } } return dp[m][n]; } };
  • C++ 字符串text1[i-1]是因为 DP 数组从 1 开始计数,而 String 从 0 开始。


模块三:编辑距离(Levenshtein Distance)

1. 思路讲解

定义dp[i][j]:将word1的前i个字符转换成word2的前j个字符所需的最少操作数。

操作有三种:插入、删除、替换。

  • 插入:在word1插入一个字符,等价于word2减少一个字符:dp[i][j-1] + 1

  • 删除:在word1删除一个字符:dp[i-1][j] + 1

  • 替换:如果两个字符不同,替换最后一个字符:dp[i-1][j-1] + 1

  • 特殊情况:如果word1[i-1] == word2[j-1],无需操作,直接继承dp[i-1][j-1]

2. 代码详解

cpp

class Solution { public: int minDistance(string word1, string word2) { int m = word1.size(), n = word2.size(); vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0)); // 初始化:word1变成空串,只能靠删除;空串变成word2,只能靠插入 for (int i = 1; i <= m; i++) dp[i][0] = i; for (int j = 1; j <= n; j++) dp[0][j] = j; for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { if (word1[i - 1] == word2[j - 1]) { // 字符相同,无需操作 dp[i][j] = dp[i - 1][j - 1]; } else { // 字符不同,取三种操作的最小值 + 1(本次操作成本) dp[i][j] = min({ dp[i - 1][j] + 1, // 删除 dp[i][j - 1] + 1, // 插入 dp[i - 1][j - 1] + 1 // 替换 }); } } } return dp[m][n]; } };
  • C++ 技巧min({a, b, c})是 C++11 以后支持的初始化列表用法,可以一次性比较多个值。


总结:C++ DP 避坑指南

  1. 数组大小:为了逻辑清晰,通常开dp[n+1]dp[m+1][n+1],牺牲一点空间换取代码可读性。

  2. 初始化

    • 求最大值时,初始化为0INT_MIN

    • 求最小值时,初始化为INT_MAX

    • 布尔型初始化dp[0] = true

  3. 遍历顺序

    • 0-1 背包:容量倒序。

    • 完全背包:容量正序。

    • 序列 DP:通常是双重循环,注意内外层逻辑。

  4. 引用传参:在函数中传递大型vector时,务必使用const vector<int>&vector<int>&,否则会复制整个数组,导致超时(TLE)。

谢谢
http://www.jsqmd.com/news/1164493/

相关文章:

  • 2026年7月最新嘉兴爱彼官方售后维修服务网点地址与客服电话 - 爱彼中国官方服务中心
  • 绍兴企业做 GEO 优化找谁靠谱?2026 年 3 家高口碑服务商实测推荐 - 品牌测评网
  • 自动驾驶数据安全与本地化部署技术解析
  • 广州万国回收价格查询及各大回收平台实测排行(2026年7月最新数据) - 万国中国官方服务中心
  • STM32F723ZE与TPA3128D2构建高性能数字音频系统
  • 2026年淄博保险纠纷律师哪家好?5位专业律师值得推荐 - 本地品牌推荐
  • DDR5 ECC 内存 3 种纠错方案对比:Side-band、On-die 与 Link ECC 实测差异
  • PicoXR与PicoOpenXR插件深度对比与选型指南
  • 2026年AI写小说软件哪个好用?10款主流工具真实测评(含大纲范例与避坑指南)
  • 北京大兴机场发布大面积航班延误预警
  • 2026年新发布:南岸宝藏夜景餐厅极高颜值推荐与选型指南 - 品牌鉴赏官2026
  • HDRP Mask Map通道打包技术:原理、合成与性能优化全解析
  • 【一线大厂Java面试题合集】第11篇-集合面试综合对比与实战
  • ai全栈day06
  • WebPShop技术架构深度解析:Photoshop专业级WebP格式支持实现原理
  • AI推理经济学:从基准测试到成本效益优化的实践指南
  • 电路等效变换实战:从Y-△到戴维宁定理的5个经典例题解析
  • 【AI】某金融机构AI岗位笔试参考题及答案解析
  • 2026年7月最新南昌爱彼官方售后客户服务热线与维修网点地址汇总 - 爱彼中国官方服务中心
  • Cube Sandbox 是一款基于 RustVMM 与 KVM 构建的高性能、开箱即用的安全沙箱服务。它既支持单机部署,也能方便地扩展到多机集群。对外兼容 E2B SDK,可在 60ms 内创建具备
  • ADP5350与TM4C129XNCZAD的低功耗嵌入式系统设计
  • MAX77654与TM4C1294的嵌入式电源管理方案设计
  • 2026年7月最新长春江诗丹顿官方售后服务网点地址及客服电话一览 - 江诗丹顿官方服务中心
  • STM32图形化配置与代码生成工具全解析
  • Unity DOTS/ECS架构实战:从零构建高性能实体系统
  • VMware OVF Tool:自动化批量导出与运维集成指南
  • 高维数据可视化方法梳理(学习笔记)
  • FPG财盛国际:长期一致性与流程清晰度如何影响体验,给出一套标准
  • Linux 进程调试神器:pstack 命令详解,一键打印线程调用栈定位死锁 / 卡顿
  • 2026年7月最新惠州万国官方售后联系电话与客户服务中心网点地址 - 万国中国官方服务中心