【算法】动态规划-力扣3题(509、70、746)

139 阅读2分钟

##1.动态规划系列

1.思路: 借鉴(代码随想录)

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情

  1. 创建dp数组来保存递归的结果

  2. 确定dp数组以及下标的含义

  3. 确定递推公式

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

  4. dp数组如何初始化

    dp[0] = 0; dp[1] = 1;

  5. 确定遍历顺序

  6. 举例推导dp数组

2.常见题型

1.背包问题

2.打家劫舍

3.股票问题

4.子序列问题

3.leetcode-3道题
1.509 斐波那契数

题目不在赘述,耳熟能详

题目已经给出推导的公式,只需要初始化特殊值,f(n)=0,f(n)=1

可以递归用公式推导,此处写dp思路

假设p、q、r(r为结果)整体为滑块,滑块像左推 ,会有以下规律

p q r

0 0 1 i=2

0 1 1 i=3

1 2 3 i=4

2 3 5 i=5

public int fib(int n) {
•        if(n<2)
•            return n;
•        int p=0,q=0,r=1;
•        for(int i=2;i<=n;i++){
•            p = q;
•            q = r;
•            r = p + q;
•        }
​
•        return r;
•    }
2.leetcode-70 爬楼梯

题目描述:每次可以爬1或者2个台阶,求爬到楼顶有多少种方法

思路:

1.n=1 1阶 1种

2.n=2 1阶+1阶 2种

2阶

3.n=3 1阶+1阶+1阶 3种(2+1)

2阶+1阶

1阶+2阶

4.n=4 1阶+1阶+1阶+1阶 5种(3+2)

2阶+1阶+1阶

1阶+2阶+1阶

1阶+1阶+2阶

2阶+2阶

推导出公式,和斐波那契一致,只是在初始化不同

public int climbStairs(int n) {
        if(n<3)
            return n;
        int p=1,q=2,r=0;
        for(int i=3;i<=n;i++){
            r = p+q;
            p =q;
            q= r;
        }
        return r;
    }
3.746 使用最小花费爬楼梯

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

这道题是爬楼梯的变种题,只是给每一个楼梯增加了费用

思路:

1.推导公式,可以见上一个题 只是我们需要分清开始和结束

起点->10->15->20->到达

起点开始,我们走1阶和2阶不用付费,到达了才给钱,所以

dp[0] = cost[0]; dp[1] = cost[1];

就能推出公式为:Math.min(dp[i-1],dp[i-2])+cost[i],我们取1阶和2阶里面最小的加上费用

但是如例子1,10,15,20 按照思路下标为2时,会被修改为10+20=30(10.15.30)并不是最小的,

所以我们用结束倒推,如果到达了终点,找走一步还是两步才是最优解

Math.min(dp[n-1],dp[n-2])

public int minCostClimbingStairs(int[] cost) {
        int n = cost.length;
        int[] dp = new int[n];
        dp[0] = cost[0];
        dp[1] = cost[1];
        for(int i=2;i<n;i++){
            dp[i] = Math.min(dp[i-1],dp[i-2])+cost[i];
        }
        //已经到达终点,看走一步还是走两步是最优解
        return Math.min(dp[n-1],dp[n-2]);
    }

\