• 代码随想录算法训练营day45|70. 爬楼梯(进阶版)|322. 零钱兑换|279.完全平方数


    70. 爬楼梯(进阶版)

    一步一个台阶,两个台阶,三个台阶,…,直到 m个台阶。问有多少种不同的方法可以爬到楼顶呢?

    1阶,2阶,… m阶就是物品,楼顶就是背包。

    每一阶可以重复使用,例如跳了1阶,还可以继续跳1阶。

    问跳到楼顶有几种方法其实就是问装满背包有几种方法。 求的是排列

    class Solution {
        public int climbStairs(int n) {
            int[] dp = new int[n + 1];
            int m = 2; //m表示最多可以爬m个台阶
            dp[0] = 1;
    
            for (int i = 1; i <= n; i++) { // 遍历背包
                for (int j = 1; j <= m; j++) { //遍历物品
                    if (i >= j)  //當前的背包容量 大於 物品重量的時候,我們才需要記錄當前的這個裝得方法(方法數+)
    			dp[i] += dp[i - j];
                }
            }
            return dp[n];
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    322. 零钱兑换

    力扣题目链接

    给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。

    你可以认为每种硬币的数量是无限的。

    示例 1:

    • 输入:coins = [1, 2, 5], amount = 11
    • 输出:3
    • 解释:11 = 5 + 5 + 1

    示例 2:

    • 输入:coins = [2], amount = 3
    • 输出:-1

    示例 3:

    • 输入:coins = [1], amount = 0
    • 输出:0

    示例 4:

    • 输入:coins = [1], amount = 1
    • 输出:1

    示例 5:

    • 输入:coins = [1], amount = 2
    • 输出:2

    提示:

    • 1 <= coins.length <= 12

    • 1 <= coins[i] <= 2^31 - 1

    • 0 <= amount <= 10^4

    • 动规五部曲

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

    背包容量: 目标值

    硬币:物品

    问:装满这个背包,最少用多少件物品

    dp[j]:凑足总额为j所需钱币的最少个数为dp[j]

    2.确定递推公式

    Math.min

    dp[j]=Math.min(dp[j],dp[j-coins[i]]+1)
    
    • 1

    3.初始化

    首先凑足总金额为0所需钱币的个数一定是0,那么dp[0] = 0;

    其他下标对应的数值呢?

    考虑到递推公式的特性,dp[j]必须初始化为一个最大的数,否则就会在Math.min(dp[j - coins[i]] + 1, dp[j])比较的过程中被初始值覆盖。

    所以下标非0的元素都是应该是最大值。

    //初始化dp数组为最大值
            for (int j = 0; j < dp.length; j++) {
                    dp[j] = Integer.MAX_VALUE;
            }
    
    • 1
    • 2
    • 3
    • 4

    4.遍历顺序求

    求最小的元素数量 ,不影响 都可以

    5.打印dp数组

    以输入:coins = [1, 2, 5], amount = 5为例

    322.零钱兑换

    代码:

    class Solution {
        public int coinChange(int[] coins, int amount) {
            int[] dp=new int[amount+1];
            //初始化 其他下标  因为要求最小所以不能赋值为0  会被覆盖
            for (int j = 0; j < dp.length; j++) {
                dp[j] = Integer.MAX_VALUE;
            }
            dp[0]=0;
            for(int i=0;i<coins.length;i++){  //遍历物品
                for(int j=coins[i];j<=amount;j++){  //遍历背包
                    if(dp[j - coins[i]] != Integer.MAX_VALUE){
                        // 如果dp[j - coins[i]]是初始值则跳过
                        dp[j]=Math.min(dp[j],dp[j-coins[i]]+1);
                    }
                }
            }
            return dp[amount]==Integer.MAX_VALUE?-1:dp[amount];
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    279.完全平方数

    力扣题目链接

    给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, …)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。

    给你一个整数 n ,返回和为 n 的完全平方数的 最少数量 。

    完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1、4、9 和 16 都是完全平方数,而 3 和 11 不是。

    示例 1:

    • 输入:n = 12
    • 输出:3
    • 解释:12 = 4 + 4 + 4

    示例 2:

    • 输入:n = 13
    • 输出:2
    • 解释:13 = 4 + 9

    提示:

    • 1 <= n <= 10^4

    • 动态规划五部曲

    1.确定dp数组的含义

    背包容量: 整数n

    物品:完全平方数 i*i

    问题:给你一个整数 n ,返回和为 n 的完全平方数的 最少数量 。

    dp[j]: 和为j时,完全平方数最少的数量为dp[j]

    2.确定递推公式

    dp[j]=Math.min(dp[j],dp[j-i*i]+1)

    每个元素的数值用i*i表示

    3.初始化

    首先凑足总金额为0所需钱币的个数一定是0,那么dp[0] = 0;

    其他下标对应的数值呢?

    考虑到递推公式的特性,dp[j]必须初始化为一个最大的数,否则就会在Math.min(dp[j - coins[i]] + 1, dp[j])比较的过程中被初始值覆盖。

    所以下标非0的元素都是应该是最大值。

    //初始化dp数组为最大值
            for (int j = 0; j < dp.length; j++) {
                    dp[j] = Integer.MAX_VALUE;
            }
    
    • 1
    • 2
    • 3
    • 4

    4.遍历顺序求

    求最小的元素数量,不影响

    5.打印dp数组

    已输入n为5例,dp状态图如下:

    279.完全平方数

    dp[0] = 0 dp[1] = min(dp[0] + 1) = 1 dp[2] = min(dp[1] + 1) = 2 dp[3] = min(dp[2] + 1) = 3 dp[4] = min(dp[3] + 1, dp[0] + 1) = 1 dp[5] = min(dp[4] + 1, dp[1] + 1) = 2

    最后的dp[n]为最终结果。

    代码:

    class Solution {
        public int numSquares(int n) {
            int[] dp=new int[n+1];
            for(int j=0;j<=n;j++){
                dp[j]=Integer.MAX_VALUE;
            }
            dp[0]=0;
            for(int i=1;i*i<=n;i++){  //遍历物品
                for(int j=i*i;j<=n;j++){   //遍历背包  背包从物品大小开始
                    dp[j]=Math.min(dp[j],dp[j-i*i]+1);  //为了下标不出现负数
                }
            }
            return dp[n];
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
  • 相关阅读:
    一、8086
    【后端框架】MyBatis(1)
    .NET合并程序集(多个dll/exe合并成一个dll)
    节日网页HTML代码 学生网页课程设计期末作业下载 清明节大学生网页设计制作成品下载 DW节日网页作业代码下载
    Excel-VBA 快速上手(二、条件判断和循环)
    带你进入桌面数控机床金工实训室
    如何使用NPM包管理器在Node.js项目中安装和管理依赖
    非常经典的Oracle基础知识
    Spring AOP 基于注解源码整理
    [附源码]计算机毕业设计企业售后服务管理系统Springboot程序
  • 原文地址:https://blog.csdn.net/xinrenne/article/details/132755825