322. 零钱兑换【完全背包:最小数】

322. 零钱兑换

给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。
计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。
你可以认为每种硬币的数量是无限的。

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

示例 2:
输入:coins = [2], amount = 3
输出:-1

示例 3:
输入:coins = [1], amount = 0
输出:0


Java代码1:完全背包、背包放入硬币的最小个数
背包:金额 amout
物品:零钱数 coins
dp[j]: 当背包容量为j时(最后一定能装满),能放入硬币的最小个数

public int coinChange(int[] coins, int amount) {
    int[] dp= new int[amount + 1];
    Arrays.fill(dp, Integer.MAX_VALUE);
    dp[0] = 0;
    for (int num : coins) {
        for (int j = num; j <= amount; ++j) {  // 硬币价值 <-> 背包容量、dp[]为最小硬币数
            if (dp[j - num] != Integer.MAX_VALUE) {  // [2] 3  dp[2]==1,dp[3] = min(dp[3], dp[1]+1)(就是说你不能只拿一个2,去装满背包容量为3的)
                dp[j] = Math.min(dp[j], dp[j - num] + 1);    // dp:[0, MAX, 1, MAX, MAX, AMX, MAX, MAX],我不能拿一个硬币2去装满背包3!往前查找dp[j]若为MAX,说明背包j是不能通过硬币装满的!
            }                       // 1 代表什么? 答:代表放入的硬币个数为1;
        }                           // 放入什么dp[]就代表什么!
    }                               // 放入这个物品的数量 = 除去num的数量 + 新放入的 1 数量
                                    // 像:(1) dp[j] = Math.max(dp[j], dp[j - num] + num);
                                    //     (2) dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]);  都是这个意思
                                    
                                    // 都是在比较大小,一个对比的是:物品个数,一个对比的是:放入一个个物品对应的价值。
                                    // 最后的核心都是一样的!
                                    // 所以它们初始化 dp 全为 0;而排列数、组合数就不 dp[j - num] + 1,含义不一样。
                                    
                                    // (1) 和 (2) 只要 bagSize 和 num 属性一致就 ok:
                                    // num 与 bagSize 都是同属性;weight[i] 和 bagSize背包容量 也是同属性!
									// 就只是用来判断:放与不放:dp[j - num] dp[j]

                                    // 至于后面加的什么,可以是:物品个数 1、num、1个物品对应的 value[i] 
                                    // 这些就代表 dp[j] 的含义:装满背包的最小物品数、用能num去装背包 能装的最大和、背包能装的最大价值
                                    
    if (dp[amount] == Integer.MAX_VALUE) { // 无法装满
        return -1;
    }
    return dp[amount];
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值