java算法day45 | 动态规划part07 ● 70. 爬楼梯 (进阶) ● 322. 零钱兑换 ● 279.完全平方数

这篇具有很好参考价值的文章主要介绍了java算法day45 | 动态规划part07 ● 70. 爬楼梯 (进阶) ● 322. 零钱兑换 ● 279.完全平方数。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

70. 爬楼梯 (进阶)

题目描述:
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬至多m (1 <= m < n)个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。
输入描述:输入共一行,包含两个正整数,分别表示n, m
输出描述:输出一个整数,表示爬到楼顶的方法数。
输入示例:3 2
输出示例:3
提示:
当 m = 2,n = 3 时,n = 3 这表示一共有三个台阶,m = 2 代表你每次可以爬一个台阶或者两个台阶。
此时你有三种方法可以爬到楼顶。
1 阶 + 1 阶 + 1 阶段
1 阶 + 2 阶
2 阶 + 1 阶

  1. 确定dp数组以及下标的含义
    dp[i]:爬到有i个台阶的楼顶,有dp[i]种方法。

  2. 确定递推公式
    在动态规划:494.目标和 (opens new window)、 动态规划:518.零钱兑换II (opens new window)、动态规划:377. 组合总和 Ⅳ (opens new window)中我们都讲过了,求装满背包有几种方法,递推公式一般都是dp[i] += dp[i - nums[j]];
    本题呢,dp[i]有几种来源,dp[i - 1],dp[i - 2],dp[i - 3] 等等,即:dp[i - j]
    那么递推公式为:dp[i] += dp[i - j]

  3. dp数组如何初始化
    既然递归公式是 dp[i] += dp[i - j],那么dp[0] 一定为1,dp[0]是递归中一切数值的基础所在,如果dp[0]是0的话,其他数值都是0了。
    下标非0的dp[i]初始化为0,因为dp[i]是靠dp[i-j]累计上来的,dp[i]本身为0这样才不会影响结果

  4. 确定遍历顺序
    这是背包里求排列问题,即:1、2 步 和 2、1 步都是上三个台阶,但是这两种方法不一样!
    所以需将target放在外循环,将nums放在内循环。
    每一步可以走多次,这是完全背包,内循环需要从前向后遍历。

  5. 举例来推导dp数组

import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        Scanner in=new Scanner(System.in);
        int n=in.nextInt();
        int m=in.nextInt();
        int[] dp=new int[n+1];
        dp[0]=1;
        for(int j=1;j<=n;j++){
            for(int i=0;i<=m;i++){
                if(j>=i){
                    dp[j]=dp[j]+dp[j-i];
                }
            }
        }
        System.out.println(dp[n]);
    }
}

时间复杂度:O(mn)
空间复杂度:O(n)

322. 零钱兑换

java算法day45 | 动态规划part07 ● 70. 爬楼梯 (进阶) ● 322. 零钱兑换 ● 279.完全平方数,java算法打卡,算法,java,动态规划
java算法day45 | 动态规划part07 ● 70. 爬楼梯 (进阶) ● 322. 零钱兑换 ● 279.完全平方数,java算法打卡,算法,java,动态规划
动规五部曲分析如下:

  1. 确定dp数组以及下标的含义
    dp[j]:凑足总额为j所需钱币的最少个数为dp[j]

  2. 确定递推公式
    凑足总额为j - coins[i]的最少个数为dp[j - coins[i]],那么只需要加上一个钱币coins[i]即dp[j - coins[i]] + 1就是dp[j](考虑coins[i])
    所以dp[j] 要取所有 dp[j - coins[i]] + 1 中最小的。
    递推公式:dp[j] = min(dp[j - coins[i]] + 1, dp[j]);

  3. dp数组如何初始化
    首先凑足总金额为0所需钱币的个数一定是0,那么dp[0] = 0;
    其他下标对应的数值呢?
    考虑到递推公式的特性,dp[j]必须初始化为一个最大的数,否则就会在min(dp[j - coins[i]] + 1, dp[j])比较的过程中被初始值覆盖。
    所以下标非0的元素都是应该是最大值。

  4. 确定遍历顺序
    本题求钱币最小个数,那么钱币有顺序和没有顺序都可以,都不影响钱币的最小个数。
    所以本题并不强调集合是组合还是排列。
    综上所述,遍历顺序为:coins(物品)放在外循环,target(背包)在内循环。且内循环正序。

  5. 举例推导dp数组

class Solution {
    public int coinChange(int[] coins, int amount) {
        int max=Integer.MAX_VALUE;
        int[] dp=new int[amount+1];
        for(int i=0;i<dp.length;i++){
            dp[i]=max;
        }
        dp[0]=0;
        for(int i=0;i<coins.length;i++){
            for(int j=coins[i];j<=amount;j++){
                if(dp[j-coins[i]]!=max){//只有dp[j-coins[i]]不是初始最大值时,该位才有选择的必要
                dp[j]=Math.min(dp[j],dp[j-coins[i]]+1);
                }
            }
        }
        return dp[amount]==max?-1:dp[amount];
    }
}

时间复杂度: O(n * amount),其中 n 为 coins 的长度
空间复杂度: O(amount)

279.完全平方数

java算法day45 | 动态规划part07 ● 70. 爬楼梯 (进阶) ● 322. 零钱兑换 ● 279.完全平方数,java算法打卡,算法,java,动态规划
java算法day45 | 动态规划part07 ● 70. 爬楼梯 (进阶) ● 322. 零钱兑换 ● 279.完全平方数,java算法打卡,算法,java,动态规划

动规五部曲分析如下:

  1. 确定dp数组(dp table)以及下标的含义
    dp[j]:和为j的完全平方数的最少数量为dp[j]

  2. 确定递推公式
    dp[j] 可以由dp[j - i * i]推出, dp[j - i * i] + 1 便可以凑成dp[j]。
    此时我们要选择最小的dp[j],所以递推公式:dp[j] = min(dp[j - i * i] + 1, dp[j]);

  3. dp数组如何初始化
    dp[0]表示 和为0的完全平方数的最小数量,那么dp[0]一定是0。
    有同学问题,那0 * 0 也算是一种啊,为啥dp[0] 就是 0呢?
    看题目描述,找到若干个完全平方数(比如 1, 4, 9, 16, …),题目描述中可没说要从0开始,dp[0]=0完全是为了递推公式。
    非0下标的dp[j]应该是多少呢?
    从递归公式dp[j] = min(dp[j - i * i] + 1, dp[j]);中可以看出每次dp[j]都要选最小的,所以非0下标的dp[j]一定要初始为最大值,这样dp[j]在递推的时候才不会被初始值覆盖。

  4. 确定遍历顺序
    我们知道这是完全背包,
    如果求组合数就是外层for循环遍历物品,内层for遍历背包。
    如果求排列数就是外层for遍历背包,内层for循环遍历物品。

class Solution {
    public int numSquares(int n) {
        int max = Integer.MAX_VALUE;
        int[] dp = new int[n + 1];
        for (int j = 0; j <= n; j++) {//初始化
            dp[j] = max;
        }
        dp[0]=0;
        for(int i=1;i*i<=n;i++){
            int weight=i*i;
            for(int j=weight;j<=n;j++){
                dp[j]=Math.min(dp[j],dp[j-weight]+1);
            }
        }
        return dp[n];
    }
}

时间复杂度: O(n * √n)
空间复杂度: O(n)文章来源地址https://www.toymoban.com/news/detail-850573.html

到了这里,关于java算法day45 | 动态规划part07 ● 70. 爬楼梯 (进阶) ● 322. 零钱兑换 ● 279.完全平方数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 算法题打卡day45-背包问题 | 70. 爬楼梯 (进阶)、322. 零钱兑换、279.完全平方数

    70. 爬楼梯 - 力扣(LeetCode) 状态:查看思路后AC。 除了常规的可以爬一或二级台阶,当题目稍微修改一下,变成可以爬m级台阶,之前的DP思路就有局限(dp[i] = dp[i-1] + dp[i-2),为了通杀这类问题,可以将题目转换为完全背包问题,可以爬的楼梯级数就是背包中的物品,楼梯总

    2024年02月11日
    浏览(33)
  • 【LeetCode题目详解】第九章 动态规划part01 509. 斐波那契数 70. 爬楼梯 746. 使用最小花费爬楼梯 (day38补)

    斐波那契数  (通常用  F(n) 表示)形成的序列称为 斐波那契数列 。该数列由  0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是: 给定  n ,请计算 F(n) 。 示例 1: 示例 2: 示例 3: 提示: 0 = n = 30 斐波那契数列大家应该非常熟悉不过了,非常适合作为动规第

    2024年02月07日
    浏览(33)
  • 算法Day38 | 动态规划,509. 斐波那契数, 70. 爬楼梯, 746. 使用最小花费爬楼梯

    动态规划是一种解决问题的算法思想。它通常用于优化问题,其中要求找到一个最优解或最大化(最小化)某个目标函数。 动态规划的核心思想是 将问题分解成更小的子问题,并通过存储子问题的解来避免重复计算 。这样,可以通过解决子问题来构建原始问题的解。动态规

    2024年02月09日
    浏览(44)
  • 力扣70. 爬楼梯(动态规划 Java,C++解法)

    Problem: 70. 爬楼梯 由于本题目中第i层台阶只能由于第 i- 1 层台阶和第 i-2 层台阶走来,所以可以联想到动态规划,具体如下: 1.定义多阶段决策模型:对于每一上台阶看作一种状态; 2.定义状态转移方程:int[] dp = new int[n + 1] 用于记录第i个台阶可以走到的走法 ;dp[i] = dp[i -

    2024年01月20日
    浏览(31)
  • 代码随想录Day32 动态规划01 LeetCodeT509 斐波那契数列 T70 爬楼梯 T746 爬楼梯的最小消耗

    动态规划首先可以解决的问题有背包问题,打家劫舍问题,股票问题,子序列问题等,主要是将一个大的问题切分成多个重叠的子问题,所以动态规划一定是上一个状态递推过来的,有一个重要的 状态转移方程, 但是这也并不是解题的全部,我们将动态规划的题目基本分为五步来完成

    2024年02月06日
    浏览(44)
  • 算法训练第三十八天|动态规划理论基础、509. 斐波那契数 、70. 爬楼梯 、 746. 使用最小花费爬楼梯

    参考:https://programmercarl.com/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html 动态规划是什么 动态规划,英文:Dynamic Programming,简称DP,如果某一问题有很多重叠子问题,使用动态规划是最有效的。 所以 动态规划中每一个状态一定是由上一个状态推导出来的 ,这一

    2024年02月04日
    浏览(31)
  • 算法记录 | Day45 动态规划

    改为:一步一个台阶,两个台阶,三个台阶,…,直到 m个台阶。问有多少种不同的方法可以爬到楼顶呢? 1阶,2阶,… m阶就是物品,楼顶就是背包。 每一阶可以重复使用,例如跳了1阶,还可以继续跳1阶。 问跳到楼顶有几种方法其实就是问装满背包有几种方法。 此时大家

    2024年02月11日
    浏览(22)
  • 动态规划之 70爬楼梯(第2道)

    题目: 假设你正在爬楼梯。需要  n  阶你才能到达楼顶。 每次你可以爬  1  或  2  个台阶。你有多少种不同的方法可以爬到楼顶呢? 题目链接:70. 爬楼梯 - 力扣(LeetCode) 示例: 解法:  假如爬到第 i 层,那要么是从第 i-1 层爬上来的,要么是从第 i-2 爬上来的。

    2024年02月13日
    浏览(35)
  • 算法刷刷刷|动态规划篇|509.斐波那契数| 70.爬楼梯| 746.使用最小花费爬楼梯| 62.不同路径| 63不同路径2| 343.正数拆分 | 96.不同的二叉搜索树

    509. 斐波那契数 斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是: F(0) = 0,F(1) = 1 F(n) = F(n - 1) + F(n - 2),其中 n 1 给定 n ,请计算 F(n) 。 70.爬楼梯 746.使用最小花费爬楼梯 给你一个整数

    2023年04月23日
    浏览(47)
  • day 45:爬楼梯进阶版;322. 零钱兑换;279. 完全平方数

    假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 一步一个台阶,两个台阶,三个台阶,…,直到 m个台阶。问有多少种不同的方法可以爬到楼顶呢? dp[j]:爬到j层一共有多少种方法。 递推公式:dp[j] += dp[j - i]; dp[0] = 1; dp[i]:目标整数为i的背包所能凑的最少硬币

    2024年02月07日
    浏览(79)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包