J. 【入门】添加最少硬币

    传统题 1000ms 256MiB

【入门】添加最少硬币

题目描述

给你一个下标从 00 开始的整数数组 coinscoins,表示可用的硬币的面值,以及一个整数 targettarget

如果存在某个 coinscoins 的子序列总和为 xx,那么整数 xx 就是一个 可取得的金额 。

返回需要添加到数组中的 任意面值 硬币的 最小数量 ,使范围 [1,target][1, target] 内的每个整数都属于 可取得的金额 。

数组的 子序列 是通过删除原始数组的一些(可能不删除)元素而形成的新的 非空 数组,删除过程不会改变剩余元素的相对位置。

输入格式

第一行输入 2 个整数 n,targetn, target, 表示 coins 数组的大小和可取的金额的最大值。

接下一行来 nn 个正整数,表示可用的硬币面值。

输出格式

输出一个数,表示需要添加的最少的硬币个数

3 19
1 4 10
2
6 19
1 4 10 5 7 19
1
3 20
1 1 1
3

提示

【样例解释 1】

  • 需要添加面值为 2288 的硬币各一枚,得到硬币数组 [1,2,4,8,10][1,2,4,8,10]
  • 可以证明从 111919 的所有整数都可由数组中的硬币组合得到,且需要添加到数组中的硬币数目最小为 22

【样例解释 2】

  • 只需要添加一枚面值为 22 的硬币,得到硬币数组 [1,2,4,5,7,10,19][1,2,4,5,7,10,19]
  • 可以证明从 111919 的所有整数都可由数组中的硬币组合得到,且需要添加到数组中的硬币数目最小为 11

【样例解释 3】

  • 需要添加面值为 44881616 的硬币各一枚,得到硬币数组 [1,1,1,4,8,16][1,1,1,4,8,16]
  • 可以证明从 112020 的所有整数都可由数组中的硬币组合得到,且需要添加到数组中的硬币数目最小为 33
请思考后再点击查看提示
  • 考虑如下贪心策略,对于样例 1
  • coins = [1, 4, 10], 显然 2 不能表示,所以应该添加 2,变成 coins = [1, 2, 4, 10]
  • 此时 1 到 7 均可以表示,那么只需添加 8 即可
  • 首先将 coins 从小到大排序,然后从小到大开始扫描
  • rr,表示当前最大能表示 11rr 的所有数
  • 如果 coins[i]>rcoins[i] \gt r,那么就得添加 r+1r + 1,此时 11r+r+1r + r + 1 都可以表示
  • 否则 coins[i]rcoins[i] \le r,那么 11r+coins[i]r + coins[i] 的数都可以表示

数据规模与限制

  • 1n105,1target1051 \le n \le 10^5, 1 \le target \le 10^5
  • 1coins[i]target1 \le coins[i] \le target
  • 1s, 1024KiB for each test case.

来源