月刊少女野崎君s322. 零钱兑换 - 力扣(Leetcode)dp
数组的定义:当目标金额为 i
时,至少需要 dp[i]
枚硬币凑出。
内层循环遍历硬币的面值
300. Longest Increasing Subsequence - 力扣(Leetcode)
最长递增
dp[i] 代表以nums[i]结尾的最长子序列长度
354. 俄罗斯套娃信封问题 - 力扣(Leetcode)
先按width升序排序,再按height降序(此时width相同的也不构成LIS),则找height的LIS就行
动态规划二位数组压缩
如果状态转移,是一个2x2的方形(一个由另外三个推出),则可以把n^2的空间复杂度降为n,
使用一维 dp ,保存临时变量来实现
72. 编辑距离 - 力扣(Leetcode)
s1[0..i] 和 s2[0..j] 的最小编辑距离是 dp[i+1][j+1]
状态转移,如何对应 插入 删除 替换 三种操作
53. 最大子数组和 - 力扣(Leetcode)
定义:dp[i] 记录以 nums[i] 为结尾的「最大子数组和」
空间压缩
1143. 最长公共子序列 - 力扣(Leetcode)
定义:s1[0..i-1] 和 s2[0..j-1] 的 lcs 长度为 dp[i][j]
目标:s1[0..m-1] 和 s2[0..n-1] 的 lcs 长度,即 dp[m][n]
base case: dp[0][..] = dp[..][0] = 0
空间压缩
712. 两个字符串的最小ASCII删除和 - 力扣(Leetcode)
516. 最长回文子序列 - 力扣(Leetcode)
二维数组
dp[i][j] 含义:dp[i][j] 代表 s[i]...s[j] 的最长回文子序列
转移方程
关建还是动态转移方程
1312. 让字符串成为回文串的最少插入次数 - 力扣(Leetcode)
可以先求最长回文子序列长度x,然后s.length() - x
416. 分割等和子集 - 力扣(Leetcode)
背包问题的延申,dp[i][j] nums[0..i]是否存在和为j的序列
518. 零钱兑换 II - 力扣(Leetcode)
dp[i][j] 的定义如下:若只使用前 i - 1 个物品(可以重复使用),当背包容量为 j - 1 时,有 dp[i][j] 种方法可以装满背包。
494. 目标和 - 力扣(Leetcode)
转为背包问题
174. 地下城游戏 - 力扣(Leetcode)
自顶向下,反着来生成
787. K 站中转内最便宜的航班 - 力扣(Leetcode)用迭代法再写一次
两点之间的加权最短距离
dp[s, k] 从起始点出发,到 s 点, 最多走k步的最短距离
1.子问题 2.构建map记录每个点的入度和入节点
剑指 Offer 19. 正则表达式匹配 - 力扣(Leetcode)
s[i..]p[j..] 的子问题是哪些
887. 鸡蛋掉落 - 力扣(Leetcode)
二分查找优化选择的方式、奇妙的状态转移
312. 戳气球 - 力扣(Leetcode)
dp[i][i]: 戳破(i.j)间所有气球,能得到的最大分数 所求为dp[0][n]
假设最后一个戳破的为k 遍历k的值找最大
dp[i][j] = dp[i][k] + dp[k][j] + nums[k]*nums[i]*nums[j]
486. 预测赢家 - 力扣(Leetcode)
dp[i][j][fir or sec] 左右范围 以及 先手或后手, 此时能获得的最大分数
dp[i][j].fir = max(piles[i] + dp[i+1][j].sec, piles[j] + dp[i][j-1].sec)
if 先手选择左边: dp[i][j].sec = dp[i+1][j].fir ( 后手也就是从剩下的里先手 )
if 先手选择右边: dp[i][j].sec = dp[i][j-1].fir
198. 打家劫舍 - 力扣(Leetcode)
// dp[i] 从第 i 间房子开始抢劫,最多能有多少钱
213. 打家劫舍 II - 力扣(Leetcode)
数值数组首位相接
也就是首和尾只取其中一个, 范围大者就行
337. House Robber III - 力扣(Leetcode)
房子是二叉树的形状
用map做备忘录来看房子是否被访问过
309. 最佳买卖股票时机含冷冻期 - 力扣(Leetcode)
一个问题系列,关建在于定义状态
dp[i][j] 第i天 持有状态为j 能获得最大收益 j:0不持有 1:持有
// 今日不持有 dp[i][0] = max dp[i - 1][1] + price[i], 今天卖了
// dp[i - 1][0] 今天啥也没干
// 今日持有 dp[i][1] = max dp[i - 2][0] - price[i] 今天要买,那前天一定是未持有
// dp[i - 1][1] 今天啥也没干
28. 找出字符串中第一个匹配项的下标 - 力扣(Leetcode)
KMP算法 影子状态的含义
每次遇到不相同的字符就要重启,关建就是重启到哪个状态(x)
X的本质,举例来说:
str = 'ababac'
pat = 'abac'
当二者一直匹配(aba)到不匹配(也就是b != c)时
理论上 pat 会从 str 的第二个字符开始 重新进行匹配,也就是 babac(去掉了头a
我们想知道能否直接得出(不匹配字符b之前的)已经计算过的 ba(同样去掉了头) 能走到 pat 的哪个位置
直接把 ba 输入已经生成的状态机中,可知道它能走到 a(也就是pat 的 X=1)
那么也就相当于我们可以从下面的 | 之后继续进行匹配了
aba|bac
a|bac
综上,所以X保存的是
当遇到不匹配字符时(设其在pat中序号为n,从0开始),
之前匹配的 pat[1] ~ pat[n - 1] 这个子字符串(去掉头 和 不匹配的尾),
输入状态机后所能走到的位置