代码随想录算法训练营第四十三天| 518. 零钱兑换 II、 377. 组合总和 Ⅳ、70. 爬楼梯 (进阶)

LeetCode 518. 零钱兑换 II

题目链接:https://leetcode.cn/problems/coin-change-ii/description/

文章链接:https://programmercarl.com/0518.零钱兑换II.html

思路

复制代码
 * 零钱兑换,每个零钱可以取多次来凑成amount
 * 完全背包问题:装满容量为amount的背包有多少种装法
 * dp[j]表示装满容量为j的背包有多少种装法,那么对于第i个物品,可以选择装,也可以不装
 * 如果不装dp[j] = dp[j-1],如果装,dp[j] = dp[j-coins[i]],
java 复制代码
    public int change(int amount, int[] coins) {
        //递推表达式
        int[] dp = new int[amount + 1];
        //初始化dp数组,表示金额为0时只有一种情况,也就是什么都不装
        dp[0] = 1;
        for (int i = 0; i < coins.length; i++) {
            for (int j = coins[i]; j <= amount; j++) {
                dp[j] += dp[j - coins[i]];
            }
        }
        return dp[amount];
    }

LeetCode 377. 组合总和 Ⅳ

题目链接:https://leetcode.cn/problems/combination-sum-iv/description/

文章链接:https://programmercarl.com/0377.组合总和Ⅳ.html

思路

复制代码
/**
 * 组合总和IV:题目可以理解为装满容量为target的有多少种装法,
 * 因为我们求的是排列数,所以要先遍历背包,在遍历物品
 * 比如,外层循环固定coins【1】,在内层循环遍历背包时,随着背包不断增加,coins【1】可以重复被添加进来,而由于外层循环固定了,
 * 因此coins【2】只能在下一次外层循环添加进不同大小的背包中,这么看的话,coins【i+1】只能在coins【i】之后了;
 * 如果先遍历背包后遍历物品,那么外层循环先固定背包大小j,然后在大小为j的背包中循环遍历添加物品,
 * 然后在下次外层循环背包大小变为j+1,此时仍要执行内层循环遍历添加物品,
 * 也就会出现在上一轮外层循环中添加coins【2】的基础上还能再添加coins【1】的情况,那么就有了coins【1】在coins【2】之后的情况了。
 */
java 复制代码
        public int combinationSum4(int[] nums, int target) {
            int[] dp = new int[target + 1];
            dp[0] = 1;
            for (int i = 0; i <= target; i++) {
                for (int j = 0; j < nums.length; j++) {
                    if (i >= nums[j]) {
                        dp[i] += dp[i - nums[j]];
                    }
                }
            }
            return dp[target];
        }

LeetCode 70. 爬楼梯 (进阶)

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

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

题目链接:https://leetcode.cn/problems/combination-sum-iv/description/

文章链接:https://programmercarl.com/0377.组合总和Ⅳ.html

思路

复制代码
 * 爬楼梯进阶:装满为n的背包有多少中装法
 * 求排列问题
java 复制代码
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int m, n;
        while (sc.hasNextInt()) {
            m = sc.nextInt();
            n = sc.nextInt();
            int[] dp = new int[n + 1];
            dp[0] = 1;
            for (int i = 1; i <= n; i++) {
                for (int j = 1; j <= m; j++) {
                    if (i - j >= 0) {
                        dp[i] = dp[i] + dp[i-j];
                    }
                }
            }
            System.out.println(dp[n]);
        }
    }
相关推荐
scx2013100415 小时前
20251214 字典树总结
算法·字典树
leiming615 小时前
MobileNetV4 (MNv4)
开发语言·算法
YGGP15 小时前
【Golang】LeetCode 136. 只出现一次的数字
算法·leetcode
YGGP15 小时前
【Golang】LeetCode 169. 多数元素
算法·leetcode
顾安r15 小时前
11.20 脚本网页 数学分支
算法·数学建模·html
少许极端15 小时前
算法奇妙屋(二十)-回文子串/子序列问题(动态规划)
java·算法·动态规划·图解·回文串·回文序列
天赐学c语言15 小时前
12.20 - 反转链表II && 传值和传地址的区别
数据结构·c++·算法·链表·leecode
如意鼠15 小时前
大模型教我成为大模型算法工程师之day20: 预训练语言模型 (Pre-trained Language Models)
人工智能·算法·语言模型
_OP_CHEN15 小时前
【算法基础篇】(三十六)图论基础之拓扑排序:从原理到实战,搞定 DAG 图的 “先后次序” 难题
c++·算法·蓝桥杯·图论·拓扑排序·算法竞赛·acm/icpc
良木生香15 小时前
【诗句结构-初阶】详解栈和队列(2)---队列
c语言·数据结构·算法·蓝桥杯