动态规划------DP基础入门

6 篇文章 0 订阅
1 篇文章 0 订阅

动态规划------DP基础入门

做题板子

  • 解答模板

    • 定义子问题
    • 定义目标
    • 写递归式与初始化条件
    • 伪代码
    • 分析时间复杂度
  • 1维子问题:

    • 输入: x [ 1... n ] x[1...n] x[1...n]序列,字符串,数组
    • 子问题: x [ 1... i ] / x [ i . . . n ] x[1...i]/x[i...n] x[1...i]/x[i...n]前缀或后缀
    • 复杂度: Θ ( n ) \Theta(n) Θ(n)
    • 应用:
      • 杆切割?
      • 最长递增子序列?
      • 上限子数组?
  • 2维子问题

    • 输入: x [ 1... n ] , y [ 1... m ] x[1...n],y[1...m] x[1...n],y[1...m]
      • 子问题: x [ 1... i ] , y [ 1... j ] x[1...i],y[1...j] x[1...i],y[1...j]
      • 复杂度: Θ ( m n ) \Theta(mn) Θ(mn)
      • 应用:编辑距离,最长公共子序列
    • 输入: x [ 1... n ] x[1...n] x[1...n]
      • 子问题: x [ i . . . j ] x[i...j] x[i...j]
      • 复杂度: Θ ( n 2 ) \Theta(n^2) Θ(n2)(不一定)
      • 应用:最优二叉查找树,矩阵连乘
  • 3维子问题

    • d ( i , j , k ) = m i n ( d ( i , j , k − 1 ) , d ( i , k , k − 1 ) + d ( k , j , k − 1 ) ) d(i, j, k) = min (d(i, j, k − 1), d(i, k, k − 1) + d(k, j, k − 1)) d(i,j,k)=min(d(i,j,k1),d(i,k,k1)+d(k,j,k1))
  • 图上的DP:

    • 在DAG上:拓扑序后转换为1D问题(DAG最短路)
    • 其他树:左右子树递归
  • 背包问题:取/不取的问题

例子

  • 最长公共子序列

    • 输入: x [ 1... n ] , y [ 1... m ] x[1...n],y[1...m] x[1...n],y[1...m]
    • 定义子问题: r [ i , j ] r[i,j] r[i,j] x [ 1... i ] 与 y [ 1... j ] x[1...i]与y[1...j] x[1...i]y[1...j]的最长公共子序列(长度)
    • 目标:求出r[n,m]
    • 初始化: r [ 0 , j ] = 0 ; r [ i , 0 ] = 0 ; r[0,j]=0;r[i,0]=0; r[0,j]=0;r[i,0]=0;
    • 递归式:
      r [ i , j ] = { r [ i − 1 , j − 1 ] + 1 , x [ i ] = y [ j ] m a x ( r [ i − 1 , j ] , r [ i , j − 1 ] ) , x [ i ] ! = y [ j ] r[i,j]=\begin{cases} r[i-1,j-1]+1,\quad\quad\quad\quad\quad x[i]=y[j] \\\\ max(r[i-1,j],r[i,j-1]),\quad x[i]!=y[j] \end{cases} r[i,j]=r[i1,j1]+1,x[i]=y[j]max(r[i1,j],r[i,j1]),x[i]!=y[j]
    • 复杂度: O ( m n ) \Omicron(mn) O(mn)
  • 其它最长公共子序列问题:

    • 允许X中元素重复出现:
      r [ i , j ] = { r [ i , j − 1 ] + 1 , x [ i ] = y [ j ] m a x ( r [ i − 1 , j ] , r [ i , j − 1 ] ) , x [ i ] ! = y [ j ] r[i,j]=\begin{cases} r[i,j-1]+1,\quad\quad\quad\quad\quad x[i]=y[j] \\\\ max(r[i-1,j],r[i,j-1]),\quad x[i]!=y[j] \end{cases} r[i,j]=r[i,j1]+1,x[i]=y[j]max(r[i1,j],r[i,j1]),x[i]!=y[j]

    • 前向后向连续公共子序列

      1. 输入: x [ 1... n ] x[1...n] x[1...n]
      2. 定义子问题: r [ i , j ] r[i,j] r[i,j]表示以x[i]开始,以x[j]结尾的最长连续子序列,只要带上连续就是这个板子
      3. 目标:求所有 r [ i , j ] r[i,j] r[i,j]的最大值
      4. 初始化: r [ i , i + 1 ] = I { x [ i ] = = x [ i + 1 ] } , r [ i , i ] = 0 r[i,i+1]=I\left\{x[i]==x[i+1]\right\},r[i,i]=0 r[i,i+1]=I{x[i]==x[i+1]},r[i,i]=0
      5. 递归式:
        r [ i , j ] = { r [ i + 1 , j − 1 ] + 1 , x [ i ] = x [ j ] 0 , x [ i ] ! = x [ j ] r[i,j]=\begin{cases} r[i+1,j-1] + 1,\quad x[i]=x[j] \\\\ 0,\quad x[i]!=x[j] \end{cases} r[i,j]=r[i+1,j1]+1,x[i]=x[j]0,x[i]!=x[j]
  • 最大连续和字串的DP解

    • 输入:x[1…n]
    • 定义子问题:r[i]是以x[i]为结尾的最大连续和字串
    • 目标:求r[1…n]的最大值
    • 初始化:r[0…n]=0;
    • 递归式:
      r [ i ] = { r [ i − 1 ] + x [ i ] , r [ i − 1 ] > 0 x [ i ] , r [ i − 1 ] ≤ 0 r[i]=\begin{cases} r[i-1]+x[i],\quad r[i-1] > 0 \\\\ x[i],\quad\quad\quad\quad\quad r[i-1]\leq0 \end{cases} r[i]=r[i1]+x[i],r[i1]>0x[i],r[i1]0
    • 伪代码:
    for i:=0 to n
      r[i] = 0 
    for i:=1 to n
      r[i]=max(x[i],x[i]+r[i-1])
    
    • 复杂度:O(n)
  • word to line问题

    • 一维的啊…写累了,这个有点难,懒得写了。
  • 其他问题:

    • 回文字串问题:注意长度的定义方式,递归式里是+2还是+1。
    • 回文串分割问题:(就感觉带分割的问题都是在找k个分割点),有 O ( n 2 ) O(n^2) On2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值