Codeforces Raif Round 1 G2. Lucky Numbers
有 $q$ 个询问每次询问的 $k$ 不变, 要求找到 $k$ 个非负数的和为 $n$. 如果这 $k$ 个数中某个数位 (个位, 十位, 百位…) 上有 $3, 6, 9$ 那么就会增加幸运值. 具体的数值如下表, $F$ 都会提前给出, 求出最大幸运值.
$1 \le n, k \le 999999, 1 \le F_i \le 10^9, 1 \le q \le 10^5$
能看出来和应该是一个背包(取一些数, 使其和为某值), 但明显不能直接背包, 因为这样复杂度至少 $O(k^2)$
注意到, 不同数字相同位置的数位交换对答案没有影响, 比如 $31, 29$ 和 $39, 21$ 对答案的贡献是一样的. 利用这个性质, 我们可以把 $k - 1$ 个数都构造成**仅由$0, 3, 6, 9$**组成(因为对答案的贡献为$0$, 所以可以含前导零), 而只剩下一个数, 可能有除 $0, 3, 6, 9$ 之外的其他数字. 也就是说, 能够构造出一种解, 使得最多只有一个数字, 每一位不全为 $0$ 或 $3$ 或 $6$ 或 $9$.
证明:
先只考虑某一位, 有两个数, 含有其他数字, 如 $\overline{a_0a_1 \dots a_x c}, \overline{b_0b_1 \dots b_x d}$.
-
如果 $c + d \le 9$, 令 $e = c + d$, 那么可以变成 $\overline{a_0a_1 \dots a_x e}, \overline{b_0b_1 \dots b_x 0}$ 或者 $\overline{a_0a_1 \dots a_x 0}, \overline{b_0b_1 \dots b_x e}$
-
如果 $c + d > 9$, 令 $f = c + d - 9$, 那么可以变成 $\overline{a_0a_1 \dots a_x 9}, \overline{b_0b_1 \dots b_x f}$ 或者 $\overline{a_0a_1 \dots a_x f}, \overline{b_0b_1 \dots b_x 9}$
这样, 本来我们需要对每一个选取的数字枚举所有至少含有$3, 6, 9$之一的所有数, 现在只需要对$k-1$个数字枚举仅含有$0, 3, 6, 9$的数. 剩下一个数字枚举所有数就行.
可是这样复杂度还是贼高.
每个数没有顺序, 各个数的每一位可以相互调换而不影响答案, 这就表示了, 实际上不需要把所有数是什么都求出来. 并且发现, 对于特定的一位, 6
的价值是3
的$2$倍, 9
的价值是3
的$3$倍, 再加上之前我们搞了一个0
过来, 0
的价值是3
的$0$倍.
可以这样想, 对于特定的一位, 我们有 $3(k-1)$ 个3
可以选择, 比如个位数选了 $3$ 个 3
, 要求选两个数, 那么可以是 $0, 9$, 或者 $3, 6$等等. 这样我们就可以对每一位用一个需要装满的01背包来做了. 直接背包的话 $6 \times 3k$ 数量级稍大. 由于每个物品(3
)重量和价值一模一样, 可以用二进制拆分.
然后还剩下一个数字, 我们对每一位直接枚举, 更新同一个dp值即可.
复杂度 $O(k + q)$
|
|