1. 动态规划专题训练概述
今天继续我们的动态规划专题训练,这是算法训练营的第38天。经过前五天的系统学习,相信大家对动态规划的基本概念、解题框架和常见题型已经有了扎实的理解。今天的训练将聚焦几个更具挑战性的动态规划问题,帮助大家进一步掌握这一重要算法范式。
动态规划作为算法领域的核心思想之一,在各类编程竞赛和实际工程问题中都有广泛应用。不同于前几天的入门和基础练习,今天的题目会涉及更复杂的状态转移关系和边界条件处理,需要大家灵活运用已掌握的知识点。
提示:建议在开始今天的训练前,先复习背包问题、子序列问题和股票买卖问题等经典动态规划模型,这对理解今天的题目会有很大帮助。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 今日训练题目解析
2.1 最长递增子序列问题
最长递增子序列(Longest Increasing Subsequence,LIS)是动态规划的经典问题。给定一个整数数组nums,找到其中最长严格递增子序列的长度。
解法思路:
- 定义dp数组:dp[i]表示以nums[i]结尾的最长递增子序列长度
- 初始化:每个元素本身就是一个子序列,初始值为1
- 状态转移方程:对于每个i,遍历所有j < i,如果nums[i] > nums[j],则dp[i] = max(dp[i], dp[j]+1)
- 最终结果是dp数组中的最大值
优化技巧:
- 可以使用二分查找将时间复杂度从O(n²)优化到O(nlogn)
- 维护一个tails数组,其中tails[i]表示长度为i+1的子序列的最小末尾元素
2.2 最长公共子序列问题
最长公共子序列(Longest Common Subsequence,LCS)是另一个经典动态规划问题。给定两个字符串text1和text2,返回它们的最长公共子序列的长度。
解法步骤:
- 定义二维dp数组:dp[i][j]表示text1前i个字符和text2前j个字符的LCS长度
- 初始化:第一行和第一列都为0,表示空字符串的LCS为0
- 状态转移:
- 如果text1[i-1] == text2[j-1],则dp[i][j] = dp[i-1][j-1] + 1
- 否则,dp[i][j] = max(dp[i-1][j], dp[i][j-1])
- 最终结
