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