
动态规划
DP啊
哎呦,帅小伙哦
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
LeetCode 516 最长回文子序列
分析dp数组的定义时,在子串s[i…j]中,最长回文子序列的长度为dp[i][j]。找状态转移需要归纳思维,说白了就是如何从已知的结果推出未知的部分。想求dp[i][j],假设你知道了子问题dp[i+1][j-1]的结果(s[i+1…j - 1]中最长回文子序列的长度)。这时候当s[i] == s[j]时 dp[i][j] = dp[i+1][j-1] + 2;当s[i] != s[j]时,dp[i][j] = max{dp[i + 1][j], dp[i][j - 1]}这个状态转移方程画画图就可以.原创 2021-05-20 22:14:27 · 146 阅读 · 0 评论 -
LeetCode 1143 最长公共子序列
分析经典Dp的题目,dp[i][j]的值是text1的前i个字符和text2的前j个字符的最长公共子序列。状态转移方程为:1)text1[i] == text2[j]时,dp[i][j] = dp[i - 1][j - 1] + 12)text1[i] != text2[j]时,dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])需要注意的是下面下标的对应情况。代码class Solution {public: int longestCommonSu.原创 2021-05-20 20:27:32 · 66 阅读 · 0 评论 -
LeetCode 72 编辑距离
分析dp[i][j]表示word1的前i个字符变到word2的前j个字符所需要的最少步数。状态转移方程如下:1)word[i] == word[j]时,dp[i][j] = dp[i-1][j-1]2)word[i] != word[j]时, dp[i][j] = min(dp[i - 1][j] + 1(删除), min(dp[i][j - 1] + 1(插入), dp[i - 1][j - 1] + 1)(替换))需要注意的是,字符串允许是空的,所以dp的大小定义成(m + 1)*(n + 1.原创 2021-05-20 17:20:06 · 68 阅读 · 0 评论 -
LeetCode 115 不同的子序列
本人解这个题用的是动态规划的思想。dp[i][j] 代表 T 前 i 字符串可以由 S j字符串组成最多个数.当s[j] != t[i],这个时候 dp[i][j] = dp[i][j - 1];当s[j] == t[i],这个时候dp[i][j] = dp[i - 1][j - 1] + dp[i][j - 1]; 其中dp[i - 1][j ...原创 2019-12-02 21:02:04 · 250 阅读 · 0 评论 -
LeetCode 5:最长回文子串
给你一个字符串 s,找到 s 中最长的 回文 子串。原创 2025-04-19 16:14:09 · 317 阅读 · 0 评论 -
LeetCode 1800 最大升序数组和
Dp原创 2022-10-07 01:04:03 · 98 阅读 · 0 评论 -
LeetCode 887 鸡蛋掉落
分析比较经典的动态规划的题目,状态有两个一个是鸡蛋的数量,另一个是楼层的高度。选择就是在哪个楼层扔鸡蛋(可能在哪个楼层扔都可以求得f,选择一个在最坏情况下,扔次数最小的情况)。代码class Solution {public: int superEggDrop(int K, int N) { vector<vector<int>> middleResults(K + 1, vector(N + 1, 0)); for (int i .原创 2021-05-26 12:42:36 · 113 阅读 · 0 评论 -
LeetCode 518 零钱兑换 II
分析这道题是一个完全背包的题目,dp[i][j]的定义如下:若只使用前i个物品,当背包容量为j时,有dp[i][j]种方法可以装满背包。代码class Solution {public: int change(int amount, vector<int>& coins) { int m = coins.size(); vector<vector<int>> dp(m + 1, vector(amount + 1.原创 2021-05-22 13:02:27 · 100 阅读 · 0 评论 -
LeetCode 416 分割等和子集
分析这道题可以转化成背包的问题,先求数组和的一半N,这个数就相当于一个容量为N的背包,在看是否存在一种装法,看是否能够将背包装满。代码class Solution {public: bool canPartition(vector<int>& nums) { int sum = 0; for(int data : nums){ sum += data; } if(sum % 2 .原创 2021-05-21 17:03:36 · 76 阅读 · 0 评论 -
0-1背包问题
问题描述:给你一个可装载重量为W的背包和N个物品,每个物品有重量和价值两种属性。其中第i个物品的重量是wt[i],价值为val[i],现在让你用这个背包装物品,最多能装的价值是多少?这个问题是一个典型的动态规划的题目,所需要做的:第一步:明确两点,状态和选择先说状态,如何才能描述一个问题局面?只要给定几个可选物品和一个背包的容量限制,就形成了一个背包问题,所以状态有两个,就是(背包容量)和(可选择的物品)。对于选择就是把东西放进背包或者不放进背包。for 状态1 in 状态1的所有取值 for 状原创 2021-05-21 16:49:30 · 130 阅读 · 0 评论 -
LeetCode 712 两个字符串的最小ASCII删除和
分析本题的思路和LeetCode583题很像,dp数组的含义非常相似,不同的是word1[i] != word2[j]时,状态的转移有些不同。代码class Solution {public: int minimumDeleteSum(string word1, string word2) { int len1 = word1.length(); int len2 = word2.length(); vector<vector<.原创 2021-05-20 21:00:09 · 92 阅读 · 0 评论 -
LeetCode 583 两个字符串的删除操作
分析dp[i][j]表示word1的前i个字符和word2的前j个字符编程相同的字符串所需要的最小的操作数。状态转移方程见代码。代码class Solution {public: int minDistance(string word1, string word2) { int len1 = word1.length(); int len2 = word2.length(); vector<vector<int>>.原创 2021-05-20 20:40:47 · 89 阅读 · 0 评论 -
LeetCode 354 俄罗斯套娃信封问题
分析这道题先对envelopes排序,按照信封的长递增,如果长度相同,按高度递减进行排序。然后问题就转化成了最长递增子序列的问题,这个转化比较巧妙,画一画即可理解。代码class Solution {public: static bool comp(const vector<int>& vec1, const vector<int>& vec2){ if(vec1[0] == vec2[0]){ return.原创 2021-05-20 18:24:48 · 188 阅读 · 2 评论 -
LeetCode 53 最大序列和
分析简单动态规划,dp[i]表示(0…i)包含位置i的最大序列和,这样状态转移方程就很好知道。代码class Solution {public: int maxSubArray(vector<int>& nums) { int ans = nums[0]; vector<int> dp(nums.size()); dp[0] = nums[0]; for(int i = 1; i < .原创 2021-05-20 15:10:52 · 81 阅读 · 0 评论 -
LeetCode 279 完全平方数
分析动态规划,dp[i]代表数i最少由几个平方数组成。第二个for的含义是每填一个dp[i]的时候可能受几个因素的影响。代码class Solution {public: int numSquares(int n) { vector<int> table(101); for(int i = 0; i < 101; i++){ table[i] = i * i; } vector&l.原创 2021-05-20 14:53:29 · 72 阅读 · 0 评论 -
LeetCode 322 零钱兑换
分析dp[i]表示数额i所转换成的最少硬币数。代码class Solution {public: int coinChange(vector<int>& coins, int amount) { vector<int> dp(amount + 1, amount + 1); dp[0] = 0; for(int i = 0; i <= amount; i++){ for(in.原创 2021-05-19 17:36:23 · 85 阅读 · 0 评论 -
LeetCode 64 最小路径和
结果分析 简单动态规划。状态转移方程dp[i][j] = dp[i - 1][j] < dp[i][j - 1]? dp[i - 1][j] + grid[i][j]: dp[i][j - 1] + grid[i][j]代码class Solution {public: int minPathSum(vector<vector<int>>& grid) { int m = grid.size(); if(m ..原创 2020-07-23 08:50:45 · 90 阅读 · 0 评论 -
LeetCode 96 不同的二叉搜索树
分析 这个题目采用画解法,画图,总结规律。 G(0) = 1; G(1) = 1; G(2) = G(0) * G(1) + G(1)*G(0) = 2; G(3) = G(0)*G(2) + G(1)*G(1) + G(2)*G(0) = 5; G(n) = G(0)*G(n-1) + G(1)*G(n-2) + ......+G(n-2)*G(1) + G(n -1)*G(0) 采用动态规划的思想编码,代码如下:...原创 2020-07-15 13:47:19 · 128 阅读 · 0 评论 -
LeetCode 120 三角形最小路径和
结果分析 下面代码是一个破坏性算法,但是可以使空间复杂度达到O(1)。思路很简单,是一个简单的动态规划。代码class Solution {public: int minimumTotal(vector<vector<int>>& triangle) { int m = triangle.size(); if(m == 0) return 0; int i,j..原创 2020-07-14 09:46:10 · 128 阅读 · 1 评论 -
LeetCode 174 地下城游戏
结果分析 解题思路是从右下角往左上角走,每次只能向左或者向上走一步。dp[i][j]表示到达dungeon[i][j]时所需要的最少血量,这样一来这道题就变的简单了,具体代码如下,但是需要注意的是,我把初始化m-1列和n-1行的代码这部分需要初始化的代码和不需要初始化的代码写到了一起,这样做的好处是减少了两次for循环,坏处是,不如把需要特殊处理的代码独立出来可读性强。代码class Solution {public: int calculateMinimumHP(vecto...原创 2020-07-12 18:10:57 · 860 阅读 · 1 评论 -
LeetCode 面试题 17.13 恢复空格
结果分析 使用DP的方法解决的,dp[i]表示sentence[i]之前可以用dictionary[]中字符串匹配的最大的长度。如果我们先忽略dictionary是一个数组(先把问题简单化,先解决sentence中只有一个字符串temp的情况),那么状态转移方程很好想。len = temp.length();如果sentence[i - len + 1,i]和temp相同,那么dp[i] = dp[i - 1] > dp[i - len ] + len ? dp[i - 1] : d...原创 2020-07-09 12:31:40 · 216 阅读 · 0 评论 -
LeetCode 718 最长重复子数组
结果思路 这是一个动态规划的题目,dp[i][j]表示,以A[i]和B[j]数组最后一个字符作为重复子数组最后一个字符的最长重复子数组的长度。这时状态转移方程是: 当 A[i] = B[j]时,dp[i][j] = dp[i - 1][j - 1] + 1; 把dp数组填充完毕,找到dp中最大的数即为所求。按照给定的测试用例,填充dp后如下:代码class Solution {public: int findLength(vector<int>& A..原创 2020-07-06 21:49:54 · 134 阅读 · 0 评论 -
LeetCode 63 不同路径
结果思路 使用动态规划求解的思路比较简单,dp[i][j]表示从obstacleGrid[0][0]开始到obstacleGrid[i][j]有多少条不同的路径。代码中前面两个while是给dp数组赋初始值。状态转移方程如下: obstacleGrid[i][j] = 1时,dp[i][j] = 1; obstacleGrid[i][j] = 0时,dp[i][j] = dp[i - 1][j] + dp[i][j - 1];(需要注意边界问题,下面代码,i,j是从2开...原创 2020-07-06 18:02:22 · 157 阅读 · 0 评论 -
LeetCode 32 最长有效括号
结果分析dp[i]表示以s[i]位置结束的最长有效括号的长度。计算括号的有效长度分为两种情况,一种是()()()...,另一种是()((()))这种情况。对于第一种情况,当s[i] = ')'时,如果 i-2 > -1 && s[i - 1] = '('时 dp[i] = dp[i - 2] + 2; 否则dp[i] = 0;对于第二种情况, 当s[i] = ')'时,如果i - 2 - dp[i - 1] >= 0 && dp[i - 2 - d原创 2020-07-05 14:32:32 · 206 阅读 · 0 评论 -
LeetCode 329 矩阵中的最长递增序列
动态规划方法: dp[i][j]表示以matrix[i][j]为结尾的最长递增序列struct myData{ int x; int y; int data;};bool cmp(const myData& myData1, const myData& myData2){ return myData1.data < m...原创 2020-04-24 13:07:10 · 295 阅读 · 0 评论 -
LeetCode 300 最长上升子序列
这道题是一道动态规划的题目。“动态规划”的两个步骤是思考“状态”以及“状态转移方程”。有的资料又将“动态规划”分为 3 步: base case:思考问题规模最小的时候,是什么情况; update function:自下而上思考这个问题,即上面的“状态转移方程”; gola:重点强调了输出是什么,很多时候输出并不一定是最后一个状态。我觉得这种分法更细致一点,“...原创 2019-11-20 23:19:12 · 111 阅读 · 0 评论