代码随想录算法训练营第四十五天|70.爬楼梯、322.零钱兑换、279.完全平方数

代码随想录算法训练营第四十五天|70.爬楼梯、322.零钱兑换、279.完全平方数

70.爬楼梯

题目描述

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬至多m (1 <= m < n)个台阶。你有多少种不同的方法可以爬到楼顶呢?

注意:给定 n 是一个正整数。

输入描述

输入共一行,包含两个正整数,分别表示n, m

输出描述

输出一个整数,表示爬到楼顶的方法数。

输入示例
3 2
输出示例
3

题解:完全背包的排列问题

  • dp[i] :到达 台阶 i 有dp[i]种方法
  • 递推公式 :dp[j]+=dp[i-j]
  • 初始化:dp[0]=1
  • 遍历顺序:target放外循环,nums放内循环,因为是排列问题,所以先遍历背包,后遍历物品
  • 打印dp数组

代码

import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        int m=sc.nextInt();
        int [] dp=new int[n+1];
        dp[0]=1;
        //排列问题都是先背包后物品
        for(int j=1;j<=n;j++){  //背包
            for(int i=1;i<=m;i++){  //物品
                if(j-i>=0)
                    dp[j]+=dp[j-i];
            }
        }
        System.out.println(dp[n]);
    }
}

322.零钱兑换

给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。

计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1

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

示例 1:

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

题解:因为可取硬币数是无限的,所以是一个完全背包问题。

  • dp[j] : 组成 j 最少需要 dp[j] 个硬币
  • 递推公式 : dp[j] = Math.max(dp[j],dp[j-weight[i]]+valeu[i])
  • 初始化:dp[0]=1
  • 遍历顺序:普通完全背包顺序,两层for都是从前到后
  • 打印dp数组

需要注意的是:为什么dp数组初始化为最大值?因为求的是最小值,根据题意,dp[0]=0,所以非零下标也初始化为0的话,最小值会被0全部覆盖,所以要初始化为最大值。

代码

class Solution {
    public int coinChange(int[] coins, int amount) {
        int max=Integer.MAX_VALUE;
        int dp[] =new int[amount+1];
        for(int j=1;j<=amount;j++){
            dp[j]=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]=Math.min(dp[j],dp[j-coins[i]]+1);
                }
            }
        }
        return dp[amount]==max?-1:dp[amount];
    }
}

279.完全平方数

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

完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,14916 都是完全平方数,而 311 不是。

示例 1:

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

题解:完全背包问题。

  • dp[j]: 和为 j 的完全平方数的最少个数是dp[j]
  • 递推公式: dp[j]=Math.min(dp[j-i*i],dp[j])
  • 初始化:dp[0]=0,求最小值,所以非零下标初始化为最大值
  • 遍历顺序:两层for 都从前向后
  • 打印dp数组

代码

class Solution {
    public int numSquares(int n) {
        int [] dp=new int[n+1];
        int max=Integer.MAX_VALUE;
        for(int i=1;i<n+1;i++){
            dp[i]=max;
        }
        dp[0]=0;
        for(int i=1;i*i<=n;i++){
            for(int j=i*i;j<=n;j++){
                if(j>=i*i)
                    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、付费专栏及课程。

余额充值