• 力扣322题、279题(完全背包)


    322、零钱兑换

    基本思想:

    每种硬币的数量是无限的------完全背包

    与518题不同,518问的是方法种类,本题问的是硬币个数

    具体实现:

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

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

    2.确定递推公式

    完全背包公式:

     dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);

    本题:dp[j] = min(dp[j],dp[j - coins[i]] + 1);

    对应到背包问题上硬币面值是物品重量,一个硬币的数量对应物品价值

    3.dp数组初始化

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

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

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

    4.确定遍历顺序

    本题的两个for循环的关系是:外层for循环遍历物品,内层for遍历背包或者外层for遍历背包,内层for循环遍历物品都是可以的

    从前向后

    5.举例

    代码:

    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 < dp.length; 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就是背包,问凑满这个背包最少有多少物品?

    具体实现:

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

    dp[i]:和为i的完全平方数的最少数量为dp[i]

    2.确定递推公式

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

    3,.初始化

    dp[0]表示 和为0的完全平方数的最小数量,dp[0] = 0

    从递推公式dp[j] = min(dp[j - i * i] + 1, dp[j]);中可以看出每次dp[j]都要选最小的,

    所以非0下标的dp[i]一定要初始为最大值,这样dp[j]在递推的时候才不会被初始值覆盖。

    4.确定遍历顺序

    两层for循环内外顺序随便

    从前到后

    5.举例推导

    代码:

    class Solution {
        public int numSquares(int n) {
            int max = Integer.MAX_VALUE;
            int[] dp = new int[n + 1];
            for (int j = 1; j <= n; j++){
                dp[j] = max;
            }
            for (int i = 1; i * i <= n; i++){
                for (int j = i * i; j <= n; j++){
                    if (dp[j - i * i] != max) {
                        dp[j] = Math.min(dp[j], dp[j - i * i] + 1);
                    }
                }
            }
            return dp[n];
        }
    }
  • 相关阅读:
    2020-2021-1学期 20202424 《网络空间安全导论》第一周学习总结
    斐波那契数列
    第五周学习总结
    第四周学习总结
    黑客偶像
    第三周学习总结
    关于罗马数字转换成阿拉伯数字的理解
    十进制转二进制(python转换代码)
    第二周学习总结
    师生关系
  • 原文地址:https://www.cnblogs.com/zhaojiayu/p/15659303.html
Copyright © 2020-2023  润新知