这里是某人的做题计划 - 动态规划专题题单的做题记录, 含有我对这些题目的原创思路, 因为做这些题时没有查看题解, 这里有些思路可能不完整或不正确, 但通过后一定会修正
思路: 在此题中, 我们存储的数据有两个, 即子串 ( 指括号匹配子串, 下同 ) 的长度, 子串的左端点或右端点, 这样我们才能确定唯一的一个子串, 也方便输出; 同时观察数据范围也可知算法时间复杂度必须为
状态定义: 定义
状态转移方程:
综上得到状态转移方程, 定义
边界条件: 全部初始化为 0 即可
思路: 在题目所给的表格中进行模拟, 容易发现类似于在表上取数, 可以从左上方走来 ( 插花了, 或者理解为选当前数 ), 也可以从左边走来 ( 不插花, 不选当前数 ) , 数据范围也允许二维 DP
状态定义: 定义
状态转移方程: 定义价值矩阵为
同时因为不可能插的花比花瓶还多, 所以如果
边界条件: 因为存在负值, 所以初始化为负无穷, 只有
思路一: 时间复杂度为
思路二: 由于数据范围显然不允许思路一中的算法通过, 考虑与运算的特殊性质, 若两个数的二进制表示中有任意一位都为 1 , 则结果非 0 , 则我们可以想到另一种状态定义, 不记录每个数对应的子序列的最大长度, 而是记录每一个二进制位, 对于所有这一二进制位为 1 的数, 以这些数为子序列的结尾所取得的最大长度
状态定义: 如思路二所言, 定义
状态转移: 此状态看似不好转移, 但其实还算容易想, 考虑对于任意一个数, 它可以接到任何一个与它有至少一个相同二进制位的数上, 并作为结尾继续转移, 因此想到将对原数组的遍历作为外层循环 ( 当前遍历到的数表示为
每次先计算其中第二个最大值, 再计算第一个, 即可完成转移
边界条件: 最大值最小为 1 , 初始设为 1 即可
思路: 考虑弱化的版本, 若没有倍数限制, 显然可以使用二维 DP 解决, 那么若有限制, 只需再加一维记录这个限制即可; 具体来说, 加上一维代表当前取到的豌豆数, 将 DP 变成可达性 DP , 豌豆数最大不超过 1000 , 因此可以开下
状态定义: 定义
状态转移: 设
边界条件: 注意当true 即可
思路一: 不要求保持原顺序 ( 否则就很简单了 ) , 将原序列排序后显然是最优的, 因为若交换两个数, 相当于将其中一个减少, 另一个增加, 对于任意两个不以这两个数为其中一端的段, 其中一段差不变, 而另一段差必定变大, 不如排序后优
思路二: 输出有没有解, 考虑可达性 DP , 由数据范围可知只能允许一维 DP , 通常的写法应该是记录以某个点为结尾合不合法
状态定义: 定义
状态转移: 根据边界条件容易得到 (
但这样会超时 ( 时间复杂度是
true 时, 下次循环最劣也从这样每个位置最多更新一次, 复杂度均摊
边界条件: 注意, 我们只知道true , 其它均不能保证, 且在遍历时当走到false 即可
思路一: 根据数据范围容易得到大概是二维 DP , 通常的写法应该是记录以某个点为左下角 ( 其它角也可以, 下同 ) 的子矩阵中的最大值
思路二: 对角线不好统计, 考虑拍扁成子矩阵的边, 因为是方阵, 边长和对角线长是一样的, 因此只要存储最大的符合条件的子矩阵的边长即可
状态定义: 定义
状态转移: 若
令
边界条件:
思路一: 首先将题目弱化, 不考虑空格对相似程度的影响, 这题就和最短编辑距离很像, 由于只有都不是空格的时候距离才有定义, 加上一维表示空格状态, 0 代表都没有空格, 1 代表 A 串此时末尾有空格, 2 代表 B 串此时末尾有空格, 如果两个串末尾都有空格, 那么删掉这两个空格显然是更优的
思路二: 想到对式子本身进行分解, 其含义相当于, 每进入一个空格段, 相似程度减去
状态定义: 定义
状态转移: 显然有 (
边界条件: 首先, 可能出现负值, 因此全部初始化为负无穷, ATGC , 而不是通常的 ATCG