NOIP 提高组 题解
NOIST2023
涂色游戏
对于每一行每一列记录一个时间戳,对于每个格子颜色即为时间戳较大的颜色。
幂次
考虑暴力,我们发现 \(O(\sqrt[3]{n})\) 的复杂度是可以接受的,所以可以枚举 \(\sqrt[3]{n}\) 内的数然后暴力往上乘,可以用一个 unordered_map
判重,时间复杂度大概为 \(O(\sqrt[3]{n} + \log_2n + \log_3n+..\log_{\sqrt[3]{n}}n)\),不是很大。
虽然看起来就很不会炸,但还是计算一下吧。
所以复杂度即为 \(O(\sqrt[3]{n} \times \log_2n)\)。
圣诞树
首先可以简单证明路径交叉一定不优。
路径 \(A \to D \to B \to C\) 一定劣于 \(A \to B \to D \to C\)
证明:
\(AD + DB + BC > AB + BD + DC\)\(AE + ED + BE + EC > AB + DC\)
\(\because EC + ED > CD, AE + BE > AB\)
\(\therefore AD + DB + BC > AB + BD + DC\)
然后就发现我们的路径实际上的形态一定是类似于从最高点开始,两边来回折返,并且中间穿插了一些在一侧方向的连续段。
于是我们设置 \(f_{l, r, 0/1}\) 表示最高点左侧有 \(l\) 个点,最高点右侧有 \(r\) 个点,当前在左 / 右侧的最小距离和。
为了记录方案,我们还需要记录每个状态的前驱然后从终点状态往回跳。对于转移,考虑枚举当前在哪一侧然后枚举下一个的点在同侧还是在异侧。
NOIP2018
货币系统
一个看起来很显然的结论,但是看题解区都在证明()看来都很严谨。
一个数字会被删除,当且仅当它可以由若干种其他面额的纸币组合得到,因为如果可以得到那么把它删除用组合替代,一定会使得新的集合更小。
背包处理能够得到的面值。
旅行
字典序这个东西是很好贪心的,考虑对每个结点的儿子排序,直接从 \(1\) 直接开始贪就结束了。
考虑基环树,我们发现基环树上一定有一条边不会被经过,枚举这条边之后做树的贪心即可,复杂度 \(O(n^2)\),常数略大,需要提前预处理出环上的点是什么,可以考虑拓扑排序。
NOIP2020
排水系统
考虑直接 topsort,然后模拟污水流的过程,写一个分数合并就结束了。
但是分数合并会爆 LL
,需要开 __int128
。
NOIP2021
报数
考虑一种类似于埃式筛的东西筛出每个数字是否合法,之后递推出答案 \(O(1)\) 回答。
数列
考虑 dp,我么设状态 \(f_{i, j, k, u}\) 表示讨论 \(S\) 的前 \(i\) 位,选了 \(j\) 个 \(a_i\),二进制中实际上,也就是表现出来的 \(1\) 数量为 \(k\),且当前要向下一位进 \(u\) 个 \(1\) 的总贡献。
对于转移,我们考虑枚举当前这位有 \(v\) 个 \(1\),那么总共选了 \(j + v\) 个 \(a_i\),表现出来的数量为 \(k + (u + v) \& 1\),进下一位的为 \((u + v) \bmod 2\)。我们此时考虑新加的贡献,我们每一种方案里都有 \(w_i^v\),总共有组合数种方案,那么转移即为
对于答案的计算,因为实际表现出来的 \(1\) 数量无关紧要,并且再往后进的数量也是无关紧要的,所以直接枚举,然后计算即可。
需要注意,当 \(k + popcount(u) > K\) 时,不能计算答案,因为我们最终的 \(S\) 的二进制表示下有了多于 \(K\) 个 \(1\)。
NOIP2022
种花
观察发现,C
和 F
的区别在于 F
在 C
下面接了一段,这个东西的方案数如果我们确定了这个 C
长什么样子就好求了,所以我们先来看 C
。
对于 C
,我们可以考虑枚举左下角的点,然后前缀和计算一些方案数。(默认下文左下角为 C
的左下角。)
如果我们设
- \(r_{i, j}\) 表示以 \((i, j)\) 为左下角时往右最大能扩展的长度。
- \(u_{i, j}\) 表示以 \((i, j)\) 为左下角时
C
的竖和上横的方案数。 - \(d_{i, j}\) 表示以 \((i, j)\) 为左下角时,往下能扩展的最长长度。
很好递推,答案枚举位置计算即可。