动态规划学习笔记(dynamic programing)

导读:

近两天开始学习动态规划,有一说一,学着真的d疼,动态规划是从暴力递归来的,一步步的推算真的让人找不到南北,不过,也有一说一,动态规划的思想确实先进,了解了动态规划的思想,问题就变得好解决多了。

动态规划的思想:若要解一个给定问题,我们需要解其不同部分(即子问题),再根据子问题的解以得出原问题的解。

线性动态规划

线性动态规划的主要特点是状态的推导是按照问题规模 i 从小到大依次推过去的,较大规模的问题的解依赖较小规模的问题的解。

单串问题

  • 依赖比 i 小的 O(1) 个子问题
    dp[n] 只与常数个小规模子问题有关,状态的推导过程 dp[i] = f(dp[i - 1], dp[i - 2], …),当 f(dp[i-1], …) = dp[i-1] + nums[i] 时,当前状态 dp[i] 仅与 dp[i-1] 有关,如爬楼梯问题,其答案只和前面两个答案相关
  • 依赖比 i 小的 O(n) 个子问题
    dp[n] 与此前的更小规模的所有子问题 dp[n - 1], dp[n - 2], …, dp[1] 都可能有关系,需将他们都遍历一遍,如最长子序列问题,其要找到前面的每一个元素对应的最长最序列

带维度单串

双串问题

一般使用二维矩阵dp来表示,有两个输入从串,长度分别为 m, n,此时子问题需要用 i, j 两个变量表示,分别代表第一个串和第二个串考虑的位置 dp[i][j]:=第一串考虑[0…i],第二串考虑[0…j]时,原问题的解。

较大规模的子问题只与常数个较小规模的子问题有关,其中较小规模可能是 i 更小,或者是 j 更小,也可以是 i,j 同时变小

一般情况下和dp[i-1][j-1], dp[i-1][j], dp[i][j-1]有关。

说了这么多,上一个题吧。leetcode1143:最长公共子序列

构建一个二维矩阵dp,当有相同元素时就在dp[i][j-1]基础上加一,否则就在dp[i-1][j-1], dp[i-1][j]取最大值,为什么这么做呢?主要有以下两点(个人见解):

  • 当两个字符相等的时候,说明匹配上了,就在原来的基础上加1。这一点是明显的,但是怎么知道上一个子序列在哪里呢?他们又不是相邻的?
  • 当他们不同的时候,选择max(dp[i-1][j-1], dp[i-1][j])是因为这样可以传递他们的最长的公共子序列的长度,为后面的有相同的打基础。

dp路径问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值