理论基础
动态规划是由上一个状态推断出来的,不像贪心只是每次取局部最优解,和前一次没关系
动态规划比较重要的是状态转移方程,解题的基本流程如下:
1.确定dp数组以及下标的含义
2.确定递推公式
3.dp数组如何初始化
4.确定遍历顺序
5.举例推到dp数组
509. 斐波那契数

最简单的方式就是递归
python
class Solution:
def fib(self, n: int) -> int:
if n==0:
return 0
if n==1:
return 1
return self.fib(n-1)+self.fib(n-2)
下面使用动态规划,时间复杂度只要O(n)
python
class Solution:
def fib(self, n: int) -> int:
if n<=1:
return n
dp = [0]*(n+1)
dp[0]=0
dp[1]=1
for i in range(2,n+1):
dp[i]=dp[i-1]+dp[i-2]
return dp[n]
70. 爬楼梯

仔细分析一下,状态转移方程和菲波那切数列是一样的,因为假设我们有n个台阶,要么是从n-1上来,要么是从n上来,这两种状态的和就是现在的状态的值
python
class Solution:
def climbStairs(self, n: int) -> int:
if n<=2:
return n
dp = [0]*(n+1)
dp[1]=1
dp[2]=2
for i in range(3,n+1):
dp[i]=dp[i-1]+dp[i-2]
return dp[n]
746. 使用最小花费爬楼梯

这个 也写出来了,但是不是那么清晰
python
class Solution:
def minCostClimbingStairs(self, cost: List[int]) -> int:
if len(cost)==2:
return min(cost[0],cost[1])
dp = [0]*(len(cost)+1)
dp[0] = 0
dp[1] = 0
dp[2]=min(cost[0],cost[1])
for i in range(3,len(cost)+1):
dp[i] = min(dp[i-2]+cost[i-2],dp[i-1]+cost[i-1])
return dp[len(cost)]
一个是这个dp数组的下标表示的是cost长度为i的情况下,需要的最小花费(到达第i个台阶所需要花费的最小体力)
状态转移方程dp[i]=min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2])
初始化的时候dp[0],dp[1]=0
python
class Solution:
def minCostClimbingStairs(self, cost: List[int]) -> int:
dp = [0]*(len(cost)+1)
dp[0] = 0
dp[1] = 0
for i in range(2,len(cost)+1):
dp[i] = min(dp[i-2]+cost[i-2],dp[i-1]+cost[i-1])
return dp[len(cost)]