Loading

abc 231 e 题解

abc 231 e

题意

\(n\) 种硬币,面值分别为 \(A_1, A_2, \dots A_N\) 元,其中 \(1 = A_1 < A_2 < A_3 \dots < A_N\),并且对于 \(1 \le i \le N - 1\) 的所有 \(i\) 都有 \(A_{i + 1}\)\(A_i\) 的倍数。

现在要用这些硬币支付 \(X\) 元,请你求出支付和找零的硬币数量的和的最小值。

  • \(1 \le N \le 60\)

  • \(1 = A_1 < \dots < A_N \le 10 ^ {18}\)

  • \(1 \le X \le 10 ^ {18}\)

思路

首先,这个题目有一个很明显会超时还有可能会爆空间的做法,完全背包

\(dp_i\) 表示凑出 \(i\) 元的最少硬币数量。

转移为

\[dp_i = \min _ {j = 1} ^ n \{dp_{i - a_j} + 1\} \]

因为支付的钱数最多为 \(2 \times X\) 元(如果支付 \(2 \times X\) 元,就需要找零 \(X\) 元,也是凑出 \(X\) 元,还需要额外加上凑出 \(2 * X\) 元的硬币数量,很明显会比直接凑出 \(X\) 元更差),所以空间复杂度为 \(O(2 \times X)\)

但是 \(X\)\(10 ^ {18}\) 那么大,根本不能用数组存下来,所以我们可以用 map 来实现。

但是,就算空间的问题解决了,时间也救不回来。

dp 的时间复杂度为 \(O(2 \times X)\),也就是 \(O(X)\)

计算答案的时间复杂度为 \(O(X)\)

总时间复杂度为 \(O(X)\),完全无法接受。

所以,我们要考虑其他方法。

其实可以发现,题目中几乎所有条件我们都用上了,但还有一句话: 对于 \(1 \le i \le N - 1\) 的所有 \(i\) 都有 \(A_{i + 1}\)\(A_i\) 的倍数。 这句话我们一直都没有用上,那么,这又代表了什么呢?

题目里还有一个条件: \(1 = A_1 < A_2 < A_3 \dots < A_N\)

这代表着任何一个数都可以被表示出来,而又有 \(A_{i + 1}\)\(A_i\) 的倍数这个条件,所以可以发现,我们可以将 \(X\) 变成一个不知道是什么进制的数,而它对应的硬币数量就是他各位数字之和。

所以我们可以列这样一个表格:

\(B_i = A_{i + 1} \div A_i (1 \le i \le N - 1)\)

位号 N \(\dots\) 2 1 0
位权 \(A_N\) \(\dots\) \(A_3\) \(A_2\) \(A_1\)
数值 \(C_N = x \div B_1 \dots \div B_N\) \(\dots\) \(C_3 = x \div B_1 \div B_2 \mod B_3\) \(C_2 = X \div B_1 \mod B_2\) \(C_1 = X \mod B_1\)

所以,对于第 \(i\) 位来说,这意味可以选择用 \(C_i\)\(A_i\),也可以用 \(1\)\(A_{i + 1}\)\(B_i - C_i\)\(A_i\)

\(dp_{i, 0 / 1}\) 表示用前 \(i\) 种硬币凑出(不出)前 \(i\) 位所用的硬币的最小数量(描述的很奇怪)

所以有转移:

\[dp_{i, 0} = \min \{dp_{i - 1, 0}, dp_{i - 1, 1}\} + C_i \]

来解释一下吧,就是如果第 \(i\) 位要用 \(C_i\)\(A_i\) 来凑的话,那么就直接取上一位的最小硬币数量,再加上 \(C_i\) 即可。

那么,这里就有一个问题了,如果第 \(i - 1\) 位是用 \(1\)\(A_i\)\(B_{i - 1} - C_{i - 1}\)\(A_{i - 1}\) 凑出来的话,\(dp_{i - 1, 1}\) 不应该在加 \(1\) 吗?

这么想也没问题,主要是写法的不同,我是把这个 \(1\) 放在 \(dp_{i - 1, 1}\) 中加的。

\[dp_{i, 1} = \min \{dp_{i - 1, 0} + 1, dp_{i - 1, 1} - 1\} + B_i - C_i \]

我们先看 \(dp_{i - 1, 0} + 1\),这里的 \(dp_{i - 1, 0}\) 就是第 \(i - 1\) 位不借位的最少硬币数量,再 \(+ 1\) 则是因为当前这一位要再借一位。

再看 \(dp_{i - 1, 1} - 1\),这个就有一点点不好懂了。

我们先将这个转移换一种方式写出来:

\[dp_{i, 1} = \min \{dp_{i - 1, 0} + 1 + B_i - C_i, dp_{i - 1, 1} - 1 + B_i - C_i\} \]

其实这个式子应该是 \(dp_{i - 1, 1} - 1 + 1 + (B_i - C_i - 1)\),第一个 \(- 1\) 是因为在前 \(i - 1\) 位已经借过一次了,而这里又要借,所以要把之前借的那一位先去掉,\(+ 1\) 是因为又要再借一位,\(B_i - C_i - 1\) 是第 \(i\) 种硬币需要找零的数量,因为第 \(i - 1\) 位借了一个,所以第 \(i\) 位所需要的硬币数量就变成 \(C_i + 1\) 了,所以就是 \(B_i - (C_i + 1)\),也就是 \(B_i - C_i - 1\)

所以总时间复杂度为 \(O(n)\),空间复杂度为 \(O(n)\)

posted @ 2023-03-08 23:29  chengning0909  阅读(24)  评论(0编辑  收藏  举报