力扣小白刷题之322题零钱兑换

    技术2023-10-12  74

    题目描述

    给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 - 1。

    思路:动态规划

    第一步:明确[状态] 和 [选择]

    状态是【背包的容量】也就是总金额 ,因为硬币数量不限制选择是【放入背包】和【不放入背包】:做出什么样的选择改变当前状态(总金额减少)

    ** 第二步:明确 dp 数组的定义**

    dp[i] = x 表示 当目标金额为 i 时,至少需要 x 枚硬币。初始化: dp[i] = amount + 1 (凑成amount金额最多需要amount个硬币(全是1元)),所以初始化为 amount + 1就相当于初始化为正无穷,便于后续取最小值。dp[0] = 0; (总金额为0 时不需要硬币)。

    ** 第三步:根据[选择],思考状态转移的逻辑**

    无论当前目标金额是多少,选择就是从面额列表 coins 中选择一个硬币,然后目标金额就会减少。选择需要 硬币数量 最少的那个结果dp[i] = min(dp[i], dp[i - coin] + 1);

    输出

    最终返回 dp[amount];

    注意:

    首先硬币的面值要小于等于当前要凑出来的目标金额;剩余的那个目标金额应该要能够凑出来再强调一次:新状态的值要参考的是以前计算出来的【有效】状态值。 因此,不妨先假设凑不出来,因为比的是小,所以设置一个不可能的数。

    代码

    注意

    要求的是【恰好】填满背包,所以初始化的时候需要赋值为一个不可能的值:amount + 1。只有在【正常值】的时候,【状态转移】才可能发生。
    Processed: 0.009, SQL: 9