NOIP 提高组 题解

NOIST2023

涂色游戏

对于每一行每一列记录一个时间戳,对于每个格子颜色即为时间戳较大的颜色。

code

幂次

考虑暴力,我们发现 \(O(\sqrt[3]{n})\) 的复杂度是可以接受的,所以可以枚举 \(\sqrt[3]{n}\) 内的数然后暴力往上乘,可以用一个 unordered_map 判重,时间复杂度大概为 \(O(\sqrt[3]{n} + \log_2n + \log_3n+..\log_{\sqrt[3]{n}}n)\),不是很大。

虽然看起来就很不会炸,但还是计算一下吧。

\[\sum_{i = 1}^{\sqrt[3]{n}}\log_i{n} < \sqrt[3]{n} \times \log_2n \]

所以复杂度即为 \(O(\sqrt[3]{n} \times \log_2n)\)

code

圣诞树

首先可以简单证明路径交叉一定不优。

路径 \(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\) 个点,当前在左 / 右侧的最小距离和。

为了记录方案,我们还需要记录每个状态的前驱然后从终点状态往回跳。对于转移,考虑枚举当前在哪一侧然后枚举下一个的点在同侧还是在异侧。

code

NOIP2018

货币系统

一个看起来很显然的结论,但是看题解区都在证明()看来都很严谨。

一个数字会被删除,当且仅当它可以由若干种其他面额的纸币组合得到,因为如果可以得到那么把它删除用组合替代,一定会使得新的集合更小。

背包处理能够得到的面值。

code

旅行

字典序这个东西是很好贪心的,考虑对每个结点的儿子排序,直接从 \(1\) 直接开始贪就结束了。

考虑基环树,我们发现基环树上一定有一条边不会被经过,枚举这条边之后做树的贪心即可,复杂度 \(O(n^2)\),常数略大,需要提前预处理出环上的点是什么,可以考虑拓扑排序。

code

NOIP2020

排水系统

考虑直接 topsort,然后模拟污水流的过程,写一个分数合并就结束了。

但是分数合并会爆 LL ,需要开 __int128

code

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\),总共有组合数种方案,那么转移即为

\[f_{i + 1, j + v, k + (u + v) \& 1, (u + v) \bmod 2} = f_{i, j, k, u} + w_i^v \times \binom{n - j}{v} \]

对于答案的计算,因为实际表现出来的 \(1\) 数量无关紧要,并且再往后进的数量也是无关紧要的,所以直接枚举,然后计算即可。

需要注意,当 \(k + popcount(u) > K\) 时,不能计算答案,因为我们最终的 \(S\) 的二进制表示下有了多于 \(K\)\(1\)

code

NOIP2022

种花

观察发现,CF 的区别在于 FC 下面接了一段,这个东西的方案数如果我们确定了这个 C 长什么样子就好求了,所以我们先来看 C

对于 C,我们可以考虑枚举左下角的点,然后前缀和计算一些方案数。(默认下文左下角为 C 的左下角。)

如果我们设

  • \(r_{i, j}\) 表示以 \((i, j)\) 为左下角时往右最大能扩展的长度。
  • \(u_{i, j}\) 表示以 \((i, j)\) 为左下角时 C 的竖和上横的方案数。
  • \(d_{i, j}\) 表示以 \((i, j)\) 为左下角时,往下能扩展的最长长度。

很好递推,答案枚举位置计算即可。

posted @ 2023-11-03 14:59  Rainsheep  阅读(109)  评论(0编辑  收藏  举报