70. 爬楼梯 (进阶)
文章讲解:https://programmercarl.com/0070.%E7%88%AC%E6%A5%BC%E6%A2%AF%E5%AE%8C%E5%85%A8%E8%83%8C%E5%8C%85%E7%89%88%E6%9C%AC.html
题目链接:https://kamacoder.com/problempage.php?pid=1067
视频讲解:https://www.bilibili.com/video/BV1uK411o7c9/
完全背包,这道题求的不是组合数,而是排列数。因此用排列去做。
public class Test {
public int climb(int m,int n){
// 1. 确定dp数组定义:到台阶j的方法数和。
int[] dp = new int[n + 1];
dp[0] = 1;
// 2. 确定递推公式,先遍历背包再遍历物品
for(int j = 1; j <= n; j++){ // 背包
for(int i = 1; i <=m ; i++){ // 物品
dp[j] += dp[j - i];
}
}
return dp[n];
}
}
题目就和上一天的377. 组合总和 Ⅳ题目一样,因为求的是排列,因此先遍历背包再遍历物品。
import java.util.Scanner;
class climbStairs{
public static void main(String [] args){
Scanner sc = new Scanner(System.in);
int m, n;
while (sc.hasNextInt()) {
// 从键盘输入参数,中间用空格隔开
n = sc.nextInt();
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. 零钱兑换
文章讲解:https://programmercarl.com/0322.%E9%9B%B6%E9%92%B1%E5%85%91%E6%8D%A2.html
题目链接:https://leetcode.cn/problems/coin-change/
视频讲解:https://www.bilibili.com/video/BV14K411R7yv/
动态规划五步骤:
public int coinChange(int[] coins, int amount) {
// 动态规划五步骤
// 1. 确定dp数组含义:dp[j]表示装满整数为j的背包,使用的最小硬币数量
// 2. 确定递推公式:dp[j-coins[i]] + 1,表示j-coins[i]个背包下,只要再放一个coins[i]凑成dp[j]就是最小硬币数量了。
// 3. 确定遍历顺序,先物品再背包
int max = Integer.MAX_VALUE;
int[] dp = new int[amount + 1];
//初始化dp数组为最大值
for (int j = 0; j < dp.length; j++) {
dp[j] = max;
}
//当金额为0时需要的硬币数目为0
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] = Math.min(dp[j],dp[j - coins[i]] + 1);
}
}
}
if(Objects.equals(dp[amount],Integer.MAX_VALUE)){
return -1;
}
return dp[amount];
}
279.完全平方数
文章讲解:https://programmercarl.com/0279.%E5%AE%8C%E5%85%A8%E5%B9%B3%E6%96%B9%E6%95%B0.html
题目链接:https://leetcode.cn/problems/perfect-squares/
视频讲解:https://www.bilibili.com/video/BV12P411T7Br/
和零钱兑换差不多。物品是
后面再回顾