动态规划基本框架

image.pngimage.png

⼀、斐波那契数列

image.png

  1. def fib(N:int):
  2. if N==1 or N==2 return 1
  3. return fib(N-1)+fib(N-2)

image.pngimage.pngimage.png

  1. def fib(N):
  2. if N<1: return 0
  3. memo=[0]*(N+1)
  4. return helper(memo,N)
  5. def helper(memo,n):
  6. if n==1 or n==2: return 1
  7. if memo[n] != 0 : return memo[n]; memo[n] = helper(memo, n - 1) + helper(memo, n - 2); return memo[n]; }

image.pngimage.pngimage.png
image.png
image.png
image.png

⼆、凑零钱问题

image.png

  1. // coins 中是可选硬币⾯值,amount 是⽬标⾦额
  2. def coinChange(coins, amount):

image.png
image.png
image.png
image.png
image.png
image.png

image.pngimage.png

  1. def coinChange(coins,amount):
  2. dp=[amount+1]*(amount+1)
  3. dp[0]=0
  4. for i in range(amount+1):
  5. for coin in coins:
  6. if i-coin<0: contine # 跳出循环
  7. dp[i]=min(dp[i],1+dp[i-coin])
  8. return dp[amount]==amount+1 ? -1 : dp[amount] # 重点语句

image.png

三、最后总结

image.png
image.png

进阶答疑

一、最优子结构详解

1、最优子结构并不是动态规划独有的一种性质,能求最值的问题大部分都具有这个性质;但反过来,最优子结构性质作为动态规划问题的必要条件,一定是让你求最值的。找最优子结构的过程,其实就是证明状态转移方程正确性的过程,方程符合最优子结构就可以写暴力解了,写出暴力解就可以看出有没有重叠子问题了,有则优化,无则 OK。
2、遍历的过程中,所需的状态必须是已经计算出来的遍历的终点必须是存储结果的那个位置。主要就是看 base case 和最终结果的存储位置,保证遍历过程中使用的数据都是计算完毕的就行,
image.pngimage.pngimage.pngimage.pngimage.png

二、dp 数组的遍历方向

image.png
股票买卖 https://www.yuque.com/u1165446/ip7hhh/flp6xo
经典动态规划:编辑距离https://www.yuque.com/u1165446/ip7hhh/pybal9
经典动态规划:最长公共子序列
image.pngimage.pngimage.pngimage.pngimage.pngimage.png

三、状态压缩

image.pngimage.pngimage.pngimage.pngimage.pngimage.pngimage.png
(绝了这里,我还傻乎乎的想D[J]是D[I][J],D[J+1]=D[I+1][J+1],换了之后,要根据新式子确定)
image.pngimage.pngimage.pngimage.pngimage.pngimage.png