zoukankan      html  css  js  c++  java
  • 力扣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];
        }
    }
  • 相关阅读:
    记录一些经常被忽略的结论
    Eclipse 各种问题解决记录
    Feign 动态URL 解决记录
    Nacos 启动失败
    多git账号配置解决方案
    记一次java.lang.StackOverflowError
    StringBuilder 以及 StringBuffer默认大小与扩容
    MySQL索引背后的数据结构及原理
    我没有高并发项目经验,但是面试的时候经常被问到高并发、性能调优方面的问题,有什么办法可以解决吗?
    istio 学习之 手动注入sidecar
  • 原文地址:https://www.cnblogs.com/zhaojiayu/p/15659303.html
Copyright © 2011-2022 走看看