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

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


70. 爬楼梯 (进阶)

教程视频:这里利用背包问题的思想拓展成每次可以爬1~m个台阶
在这里插入图片描述
思路
1、dp[j]定义:到第 j 层的方法数
2、递推公式:dp[j]+=dp[j-m[i]];此时物品的重量和价值都为每次爬的台阶数
3、dp初始化:dp[0]=1;其余下标均初始化为0
4、遍历顺序:根据示例2,这是完全背包求排列问题,外层for循环正向遍历背包容量,内层遍历物品
5、打印结果

解法一:动态规划

class Solution {
    public int climbStairs(int n) {
        int[] m={1,2};//模拟每次能爬1~2曾台阶,表示背包问题的物品
        int[] dp = new int[n+1];
        dp[0]=1;
        for(int j=1;j<=n;j++){
            for(int i=0;i<m.length;i++){
                if(j>=m[i])dp[j]+=dp[j-m[i]];
            }
        }
        return dp[n];
    }
}

322. 零钱兑换

教程视频:https://www.bilibili.com/video/BV14K411R7yv
在这里插入图片描述
思路:这是一个完全背包问题,其中amount为背包容量,硬币价值为物品重量,求的是最少硬币数量。
1、dp[j]定义:背包容量为 j 时使用的最少硬币数量。
2、递推公式:dp[j]=Math.min(dp[j],dp[j-coins[i]]+1);
3、dp初始化:dp[0]=0; 因为求的是最小值,其他下标要初始化为最大整数
4、遍历顺序:求的是完全背包的结果长度,组合和排列都可以,这里采用组合的求法。外层for遍历物品,内层for正序遍历背包容量
5、打印结果

解法一:动态规划

class Solution {
    public int coinChange(int[] coins, int amount) {
        int[] dp = new int[amount+1];

        //初始化dp数组
        dp[0]=0;  //当金额为0时需要的硬币数目为0
        for(int i=1;i<=amount;i++){
            dp[i]=Integer.MAX_VALUE;
        }

        for(int i=0;i<coins.length;i++){
            for(int j=coins[i];j<=amount;j++){//正序遍历:完全背包每个硬币可以选择多次
                if(dp[j-coins[i]]!=Integer.MAX_VALUE){//这里需要判断是否为最大值,否则最大值+1会溢出为-2147483648	
                    dp[j]=Math.min(dp[j],dp[j-coins[i]]+1);
                }
            }
        }
        return dp[amount]==Integer.MAX_VALUE? -1 : dp[amount];
    }
}

279.完全平方数

教程视频:https://www.bilibili.com/video/BV12P411T7Br
在这里插入图片描述
思路:这是一个完全背包问题,其中 n 为背包容量,完全平方数为物品重量,求的是最少完全平方数的数量。总体与上一题322. 零钱兑换一样,这里的难点在于物品数量随背包容量变化,即物品m满足m*m<=n
1、dp[j]定义:背包容量为 j 时使用的最少完全平方数的数量。
2、递推公式:dp[j]=Math.min(dp[j],dp[j-m[i]]+1);
3、dp初始化:dp[0]=0; 因为求的是最小值,其他下标要初始化为最大整数
4、遍历顺序:求的是完全背包的结果长度,组合和排列都可以,这里采用组合的求法。外层for遍历物品,内层for正序遍历背包容量
5、打印结果

解法一:动态规划

class Solution {
    public int numSquares(int n) {
        int[] dp = new int[n+1];
        //初始化dp
        for(int i=1;i<=n;i++)dp[i]=Integer.MAX_VALUE;

        for(int i=1; i*i<=n;i++){
            for(int j=i*i;j<=n;j++){
                if(dp[j-i*i]!=Integer.MAX_VALUE){
                    dp[j] = Math.min(dp[j], dp[j-i*i]+1);
                }
            }
        }
        return dp[n];
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值