爬楼梯——动态规划

  • Post author:
  • Post category:其他





题目一

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?



解法一:动态规划

将dp[i]数组定义为到达第i阶楼梯有多少种方法,由每次可以爬1或2阶可以得到递推公式:





d

p

[

i

]

=

d

p

[

i

1

]

+

d

p

[

i

2

]

dp[i]=dp[i-1]+dp[i-2]






d


p


[


i


]




=








d


p


[


i













1


]




+








d


p


[


i













2


]







其中,dp[i-1]、dp[i-2]分别为到达第i-1、i-2阶楼梯有多少种方法。然后再确定边界条件,dp[1]=1,dp[2]=2。这样得出来的实现过程时间复杂度和空间复杂度都是o(n),可以利用滚动数组的思想将空间复杂度降为常数,如下面代码:

class Solution {
public:
    int climbStairs(int n) {
        if(n<=2)
            return n;
        int dp1=1,dp2=2,dp3;
        for(int i=3;i<=n;++i)
        {
            dp3=dp1+dp2;
            dp1=dp2;
            dp2=dp3;
        }
        return dp3;
    }
};



题目二

给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。

你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。

请你计算并返回达到楼梯顶部的最低花费。



解法:

此题的dp[i]数组可以定义为到达第i阶楼梯的最低花费,递推公式为:





d

p

[

i

]

=

m

i

n

(

d

p

[

i

1

]

+

c

o

s

t

[

i

1

]

,

d

p

[

i

2

]

+

c

o

s

t

[

i

2

]

)

dp[i]=min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2])






d


p


[


i


]




=








m


i


n


(


d


p


[


i













1


]




+








c


o


s


t


[


i













1


]


,




d


p


[


i













2


]




+








c


o


s


t


[


i













2


]


)







确定边界条件:

dp[0]=0,dp[1]=0

同样利用滚动数组的思想降低空间复杂度,代码如下:

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        int p=0,q=0,r;
        for(int i=2;i<=cost.size();++i)
        {
            r=min(q+cost[i-1],p+cost[i-2]);
            p=q;
            q=r;
        }
        return r;
    }
};



版权声明:本文为weixin_44891861原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。