
动态规划
文章平均质量分 66
动态规划
山顶夕景
互联网大厂AI算法工程师。实践出真知。
展开
-
动态规划入门
1.动态规划DP(1)题目特点2.DP解题步骤三种硬币,分别面值为2、5、7元(每种硬币都有足够多),需要买一本书27元,求如何用最少的硬币组合正好付清(不需要对方找钱)。(1)确定状态开一个数组,数组的每个元素f[i]或者f[i][j]代表什么;确定状态需要2个意识:1)最后一步;2)子问题。(2)转移方程(3)初始条件+边界情况初始条件即用转移方程算不出来(需要手工定义)。边界:不要数组越界。(4)计算顺序小结...原创 2021-01-21 22:06:02 · 897 阅读 · 0 评论 -
【Leetcode152】乘积最大子数组(动态规划)
(0)读懂题意:题目的“连续”是指位置的连续,而不是说数字的连续,这是个大坑。(1)确定状态:定义两个状态来记录当前子数组的最大乘积、最小乘积。因为在处理负数时,最小乘积乘以负数可能变为最大乘积。`dp_max[i]`表示以`nums[i]`结尾的子数组的最大乘积、`dp_min[i]`表示以`nums[i]`结尾的子数组的最小乘积。(2)状态转移方程:对于每个元素`nums[i]`,我们的`dp_max[i]`和`dp_min[i]`可以从这三个数中确定:- 只包含当前元素 `nums[i]`。原创 2024-09-08 20:46:16 · 584 阅读 · 0 评论 -
【Leetcode剑指 Offer II 091】粉刷房子(动态规划 | 滚动数组)
加上这种只需要求出【最值】的题目经常使用dp;因为每个房子能刷成三种颜色,即三种状态,加上不同的房子位置这个维度,可以令。有关,所以可以使用【滚动数组】优化计算复杂度,这个滚动数组即大小为颜色种类数。数组的三个数的最小值为按规矩粉刷房子的最小总成本。第0个房子左边木有房子,直接赋值当前房子的三种初值,已知不同房子刷成不同颜色的价格矩阵。个房子的粉刷情况都是符合题意时,这。个房子所需要的最少话费成本。(3)初始状态 + 边界情况。取值为0,1,2)表示:第。计算到最后一个房子时,即。原创 2023-03-19 15:51:49 · 377 阅读 · 0 评论 -
【Leetcode72】编辑距离(动态规划)
编辑距离可以通过以下三种操作进行计算:插入一个字符、删除一个字符、替换一个字符。初始条件:也只有两个字符串都相同或者都是空时编辑距离才为0,先全都将。根据状态转移方程,下标大的dp值都能从下标小的dp值计算得到,所以。边界:如果word1和word2其中一个没字母,即。个单词,变换到word2中前。个字符,最少需要的动作次数。,即一路加到底和一路减到底。(3)边界+初始条件。是边界情况,值分别为。原创 2022-12-10 15:41:03 · 1631 阅读 · 0 评论 -
【LeetCode139】单词拆分(完全背包dp)
1.题目2.思路为啥说是完全背包呢:单词=物品,字符串=背包,而单词能否组成字符串s,就是背包能否装满物品;并且是可以重复使用字典中的单词,即背包中可以重复使用。(1)确定状态dp[i]dp[i]dp[i]为true时表示前i的(字符串长度为i)可以拆分为一个或多个正常单词(字典里能找得到的),即字符串s的前i位能用wordDict中的单词表示。(2)转移方程如果确定dp[j] 是true,且 [j, i] 这个区间的子串出现在字典里,那么dp[i]一定是true。(j < i)。所原创 2021-05-25 00:36:52 · 851 阅读 · 0 评论 -
【LeetCode剑指offer47】礼物的最大价值(简单dp)
文章目录一、题目二、思路三、代码一、题目二、思路基础题。拿到题目,“最大价值”、路线问题,可以发现和以前做的【LeetCode62】不同路径(dp)是一个思路的,都是规定从左上角,每次只能向右or向下移动一格,于是那题从当前状态考虑时,需要将上方格子的dp值和左方的dp值相加(因为那里是求路径方法数),但是本题是取max(因为这里是求一条路径,该路径使得礼物价值最大)。(1)确定状态状态f(i,j)f(i, j)f(i,j)表示到达当前(i,j)(i, j)(i,j)坐标位置时能够拿到的礼物最大原创 2022-04-02 19:59:32 · 929 阅读 · 0 评论 -
【LeetCode53】最大子数组和(动态规划)
一、题目二、思路(1)确定状态dp[i]dp[i]dp[i]表示nums中以nums[i]结尾的最大子序和。(2)状态转移方程(描述子问题之间的联系)假设数组nums[i]值全部严格大于0,则一定有:dp[i]=max(dp[i−1]+nums[i],nums[i])dp[i] = max(dp[i-1]+nums[i],nums[i])dp[i]=max(dp[i−1]+nums[i],nums[i])但是dp[i-1]可能是负数的,分类讨论:如果dp[i-1]大于0,可以把nums[原创 2022-03-05 10:24:02 · 749 阅读 · 0 评论 -
【LeetCode剑指offer49】丑数(小顶堆或DP)
一、题目二、思路求前k大经常用到优先级队列,小顶堆,循环将符合要求的丑数加入小顶堆,取k次堆顶元素即可让堆顶为第k个丑数。而逐个加入丑数即加入2x2x2x、3x3x3x、5x5x5x进入集合(去重)即可。注意这里加入小顶堆的元素不能是int类型,否则会报错overflow(因为next = temp * factor后可能会越界):Line 17: Char 33: runtime error: signed integer overflow: 429981696 * 5 cannot be rep原创 2022-02-05 23:02:05 · 841 阅读 · 0 评论 -
【LeetCode343】剪绳子(动态规划)
一、题目二、思路(1)确定状态dp[i]是将正整数i拆成2个及其以上的正整数后,求所有数的乘积值。(2)状态转移方程当 i≥2 时,假设对正整数 i 拆分出的第一个正整数是 j(1≤j<i),则有以下两种方案:1)将 i 拆分成 j 和 i−j 的和,且 i−j 不再拆分成多个正整数,此时的乘积是 j×(i−j);2)将 i 拆分成 j 和 i−j 的和,且 i−j 继续拆分成多个正整数,此时的乘积是 j×dp[i−j]。因此,当 j 固定时,有 dp[i]=max(j×(i−j),原创 2022-02-01 19:43:33 · 881 阅读 · 0 评论 -
【LeetCode剑指offer46】把数字翻译成字符串(动态规划)
一、题目二、思路字母只有26个英文字母,数字上不超过2位数,本题本质上就是青蛙跳阶梯类型(数字可以是一位,或者两位),只不过需要赋值前进行判断。(1)确定状态dp[i]表示前i个数字的翻译方法可能个数。(2)转移方程只有两种情况可以进行组合翻译:前一个数字为1是,则必然满足[10,25]区间,可以和当前数字组合翻译若前一个数组为2,且当前数字<=5,则满足[10,25]区间,可以组合翻译而如果是单独翻译,则翻译方法数不变:dp[i] = dp[i - 1]。(3)原创 2022-01-31 13:59:33 · 791 阅读 · 0 评论 -
【LeetCode1262】 可被三整除的最大和(动态规划)
一、题目提示:1 <= nums.length <= 4 * 10^41 <= nums[i] <= 10^4二、思路要从给出的数组中,找到一小坨数满足和能被3整除。dp[i][*]表示在num[i]中,被3整除后的余数为*的最大数(和)。2.1 确定状态对于每种状态,有2种选择:选择当前元素;不选择当前元素: dp[i][*] = max{dp[i-1][*],dp[i-1][*] + nums[i]} (* 取值为 0,1,2)2.2 转移方程(1)零状原创 2022-01-29 16:18:30 · 1382 阅读 · 0 评论 -
【LeetCode42】接雨水(dp或双指针or单调栈)
一、题目二、思路下面将讲解如何一步步找到优化解,面试时候也是这样(需要体现一个思考的过程):(1)最简单的思路(会超时)从左往右逐个遍历,每次来到当前的第iii个位置时,需要确定当前位置的左边的最大值,和,当前位置的右边的最大值(这里要找左右两边的最高值大家可以再想下,要围起积水是需要两个高的),而且我们每次计算的积水单位不是一坨连起来的积水,而是当前第iii个位置的积水(如果有)。总之,时间复杂度是O(n2)O(n^2)O(n2),空间复杂度是O(1)O(1)O(1)。Leetcode官方题解是原创 2021-09-12 20:40:38 · 708 阅读 · 0 评论 -
【LeetCode279】完全平方数(完全背包问题)
文章目录1.题目2.思路3.C++代码4.Python代码Reference1.题目2.思路并没有让你输出所有满足情况的具体方案,问的是满足情况的(最少数目的)时的【平方数最少的数量】,这种问题就是用dp了,和之前的拼硬币一样(每种币值的硬币不限量)是完全背包问题。动态规划其实也就是遍历,只不过将中间值用空间储存起来了,便于计算了.(1)确定状态dp[i] 表示和为 i 的 nums 组合中完全平方数最少有 dp[i] 个.(2)转移方程确定状态转移方程需要2个意识:1)最后一步;2)子问原创 2021-07-05 01:07:36 · 1047 阅读 · 0 评论 -
【LeetCode198】打家劫舍(动态规划)
1.题目2.思路(1)确定状态对于每个屋子的判定,nums[i]nums[i]nums[i]表示当前第i个屋子的金额,而dp[i]dp[i]dp[i]来表示前i间房能偷到的最高总金额。(2)转移方程因为对于每间屋子来说,只有【偷】和【不偷】两种选择,dp[i]=max(dp[i−2]+nums[i],dp[i−1])dp[i] = max(dp[i-2]+nums[i],dp[i-1])dp[i]=max(dp[i−2]+nums[i],dp[i−1])(3)初始条件+边界情况只有一间房子原创 2021-06-04 00:02:02 · 662 阅读 · 0 评论 -
【LeetCode64】最小路径和(简单dp,注意思路-回溯->记忆化搜索->dp->空间压缩)
1.题目2.思路(1)确定状态dp[i][j]dp[i][j]dp[i][j]表示从(i,j)(i,j)(i,j)到右下角(终点)的最短路径(2)转移方程(3)初始条件+边界条件dp[0][0] = grid[0][0](4)计算顺序i和j均从0开始即可。注意:(超级牛逼题解——也要学学回溯->记忆化搜索->dp->空间压缩)3.代码class Solution: def minPathSum(self, grid: List[List[int]])原创 2021-05-22 19:25:48 · 747 阅读 · 0 评论 -
【LeetCode322】零钱兑换
一、题目二、思路本题在dp入门中有讲,确定状态转移方程。三、代码class Solution {public: int coinChange(vector<int>& coins, int amount) { int maxn=0x07ffffff;//无穷大 //coins.resize(amount+1); int n=coins.size();//硬币的个数 vector<i原创 2021-01-22 11:25:30 · 718 阅读 · 0 评论 -
【LeetCode】青蛙跳台阶(不要越界了)
1.题目2.思路入门dp:最后一步要么跳一步,要么跳两步到终点,从而得到递推式即斐波那契数列。主要是记录一个愚蠢的错误,一开始我sb没判断n为0时就return,而当n=0时,后面的那句dp[1]=1也就会数组越界。。。。或者直接就对dp数组赋初值全部为1,就不用判断n=0了。3.代码class Solution {public: int numWays(int n) { vector<int>dp(n+1,0); if(n==0) ret原创 2021-02-02 01:26:23 · 780 阅读 · 0 评论 -
【LeetCode62】不同路径(dp)
1.题目2.思路简单dp。(1)确定状态:最后一步:无论机器人用什么方式到达右下角,最后的一步肯定是向右或者向下,即右下角坐标为(m-1,n-1)时,机器人前一步一定是在(m-2,n-1)或(m-1,n-2)。子问题:如下面所说。状态:设f[i][j]f[i][j]f[i][j]为机器人从左上角走到(i,j)(i,j)(i,j)。(2)转移方程:(3)初始条件+边界情况:初始条件:f[0][0]=1f[0][0]=1f[0][0]=1,即机器人只有一种方式到左上角(原地不动)。边界原创 2021-01-23 00:18:39 · 763 阅读 · 1 评论 -
【LeetCode53】最大子序和(简单dp)
1.题目2.思路3.代码(1)确定状态(2)转移方程(3)初始条件+边界情况(4)计算顺序原创 2021-01-28 20:44:41 · 677 阅读 · 0 评论 -
【LeetCode96】不同的二叉搜索树(dp)
1.题目2.思路3.代码原创 2021-02-01 16:14:21 · 822 阅读 · 0 评论 -
【LeetCode1143】最长公共子序列(dp)
1.题目2.思路(1)确定状态dp[i][j]dp[i][j]dp[i][j]表示字符串1[1、2…i]和字符串2[1、2…j]的最长公共子序列,这里让下标为1即为字符串的第一位。(2)状态转移方程相等时比较好理解,注意不相等时是选最大值的(因为原字符串1和新增的字符串2之间的LCS可能增加,而新增的字符串1和原字符串2之间的LCS也会)。if (text1[i - 1] == text2[j - 1]) { dp[i][j] = dp[i - 1][j - 1] + 1;} el原创 2021-02-21 10:03:24 · 747 阅读 · 0 评论 -
【LeetCode300】最长递增子序列LIS(dp)
1.题目2.思路(1)确定状态dp[i]dp[i]dp[i]表示以nums[i]为结尾的最长递增子序列长度(和最大连续子问题一样,以nums[i]结尾是强制的要求),(2)状态转移方程dp[i]=max(dp[j])+1dp[i]=max(dp[j])+1dp[i]=max(dp[j])+1,且0<=j<i,nums[j]<num[i]0<=j<i,nums[j]<num[i]0<=j<i,nums[j]<num[i]。——举个栗子:序列原创 2021-02-20 23:03:52 · 698 阅读 · 0 评论 -
【LeetCode121】买卖股票的最佳时机(附dp总结图)
1.题目2.思路(1)确定状态当卖出价固定时,买入价越低获得利润越大,即如果在扫描到数组中的第i个数字时,只要能够记住之前的i-1个数字中的最小值,就能算出在当前价位卖出时可能得到的最大利润。(2)状态转移方程$$(3)边界条件+初始情况(4)计算顺序3.代码...原创 2021-02-02 22:11:07 · 854 阅读 · 0 评论 -
【LeetCode122】买卖股票的最佳时机II(比I多了个多次买卖)
1.题目2.思路比之前的I题【LeetCode121】买卖股票的最佳时机(附dp总结图)多了条件:可以多次买卖,但不能同时参与多笔交易。——因此区别就是:dp[i][1]dp[i][1]dp[i][1]即第i天持股时的状态,2种可能情况:1)前一天持股。2)前一天不持股,即今天买了股票(现金数减少prices[i]),由于整个过程只交易一次,所以今天是整个过程的第一次买股票,即第i天的现金数为dp[i−1][0]−prices[i]dp[i-1][0]-prices[i]dp[i−1][0]原创 2021-02-11 23:38:11 · 1937 阅读 · 3 评论