dp和贪心的区别在于dp是与之前的dp状态相关的,二贪心并没有状态的推导,只是局部解为全局解
dp五部曲:确定下标含义.确定递推公式.初始化,如何遍历,举例验证
509. Fibonacci Number
这道题就很简单了,基本的都给了
Way1:
dp下标代表i对应的值是多少,其他的都有了直接用
class Solution:
def fib(self, n: int) -> int:
dp=[0 for _ in range(n+1)]
if n==0:
return 0
if n==1:
return 1
dp[0]=0
dp[1]=1
for i in range(2,n+1):
dp[i]=dp[i-1]+dp[i-2]
return dp[-1]
70. Climbing Stairs
这道题就要稍微思考一下了,因为不是所有的都给了
Way1:
dp[i]代表到i步为止一共有多少种方法.初始要考虑i=1和i=2的情况.i=0不用考虑
class Solution:
def climbStairs(self, n: int) -> int:
if n==1:
return 1
dp=[0 for _ in range(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[-1]
746. Min Cost Climbing Stairs
这道题就要考虑清楚了.首先dp[i]代表的是到当前步最小的花销.其次对于当前步来说dp[i]和dp[i-1],dp[i-2],cost[i-1],cost[i-2]都有关.初始化数组要初始化到len(cost)+1,因为最后要越过整个cost数组
Way1:
按照上面的分析递推公式为dp[i]=min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2]) ,注意遍历从2开始
class Solution:
def minCostClimbingStairs(self, cost: List[int]) -> int:
dp=[0 for _ in range(len(cost)+1)]
for i in range(2,len(cost)+1):
dp[i]=min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2])
return dp[-1]
Way2:
这种方法更加巧妙,直接改cost数组,但是cost[i]代表到未来两步内的最小花销,所以最后要取cost[-1]和cost[-2]的最小值, 遍历还是从2开始
class Solution:
def minCostClimbingStairs(self, cost: List[int]) -> int:
for i in range(2,len(cost)):
cost[i]=min(cost[i-1],cost[i-2])+cost[i]
return min(cost[-1],cost[-2])