动态规划:爬楼梯及三种变形

动态规划:爬楼梯

一、70. 爬楼梯

1.1 解法一:递归

0, 1, 2, 3, 5, 8, 13, 21, 34, 55…

    /**
     * 递归
     * @param n
     * @return
     */
    public static int solve01(int n) {
        if (n<=2) return n;
        return solve01(n-1) + solve01(n-2);
    }

1.2 解法三:递归+记忆化搜索

    /**
     * 递归+记忆化搜索
     * @param n
     * @return
     */
    public static int solve02(int n) {
        int[] a = new int[n+1];
        return solve02(n, a);
    }

    private static int solve02(int n, int[] a) {
        if (n<=2) return n;
        if (a[n]!=0) return a[n];
        a[n] = solve02(n-1, a) + solve02(n-2, a);
        return a[n];
    }

1.3 动态规划

    /**
     * 动态递推
     * @param n
     * @return
     */
    public static int solve03(int n) {
        if (n<=2) return n;
        int x=1, y=2, res=0;
        for (int i=3; i<=n; i++) {
            res = x + y;
            x = y;
            y = res;
        }
        return res;
    }

二、如果一次可以上1、2、3步,有多少种方法

    /**
     * 爬楼梯: 一次可以上 1、2、3 阶台阶
     * @param n
     * @return
     */
    public static int solve(int n) {
        if (n<=2) return n;
        if (n==3) return 4;
        int x = 1, y = 2, z = 4, res = 0;
        for (int i=4; i<=n; i++) {
            res = x + y + z;
            x = y;
            y = z;
            z = res;
        }
        return res;
    }

三、如果每次可以上1、2、3阶台阶,并且相邻的步伐不能相同,有多少种方法

    /**
     * 走n阶台阶: 一次可以走 1、2、3 步,相邻步数不能相同
     * @param n
     * @return
     */
    public static int solve(int n) {
        if (n<=2) return n;
        if (n==3) return 2;
        // 走n阶台阶,第一步可以走1、2、3
        int[][] dp = new int[n+1][4];
        // n=1 时,第一步只能走 1步
        dp[1][1] = 1;
        // n=2 时, 第一步只能走 1步
        dp[2][2] = 1;
        // n=3 时,第一步可以走 1 步、2步
        dp[3][1] = 1;
        dp[3][2] = 1;
        dp[3][3] = 1;

        for (int i=4; i<=n; i++) {
            // 走i步:第一步走1步=第二步走2步+第二步走3步
            dp[i][1] = dp[i-1][2] + dp[i-1][3];
            // 走i步:第一步走2步=第二步走1步+第二步走3步
            dp[i][2] = dp[i-2][1] + dp[i-2][3];
            // 走i步:第一步走3步=第二步走1步+第二步走2步
            dp[i][3] = dp[i-3][1] + dp[i-3][2];
        }
        // 上n阶台阶 = 第一步走1步 + 第一步走2步 + 第一步走3步
        return dp[n][1] + dp[n][2] + dp[n][3];
    }

四、746. 使用最小花费爬楼梯

4.1 动态规划

    public int minCostClimbingStairs(int[] cost) {
        int n = cost.length;
        if (n<2)return 0;
        int[] dp = new int[n+1];
        dp[0] = 0;
        dp[1] = 0;
        for (int i=2; i<=n; i++) {
            dp[i] = Math.min(dp[i-1]+cost[i-1], dp[i-2]+cost[i-2]);
        }
        return dp[n];
    }

4.2 动态规划:空间优化

    public int minCostClimbingStairs(int[] cost) {
        int n = cost.length;
        int pre = 0;
        int cur = 0;
        for (int i=2;i<=n; i++) {
            int t = cur;
            cur = Math.min(cur + cost[i-1] , pre + cost[i-2]);
            pre = t;
        }
        return cur;
    }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值