退役选手的 NOIP 2018 提高组题解 QAQ
题面
Day1
Day2
数据
下载地址:NOIP 2018 提高组测试数据
铺设道路
Description
有 $n$ 个连续的区域,第 $i$ 个区域下陷的深度为 $d_i$。你每次可以选择一段连续的区间 $[L,R]$,使这段区间内每个区域的深度减少 $1$,但是必须保证任何时刻 $d_i\geqslant 0$。求将所有区域的深度都变为 $0$ 的最短时间。
数据范围:$1\le n\le 10^5$,$0\le d_i\le 10^4$
Solution
我在考场上的第一个反应就是分治,对于当前区间找到最小值,这个最小值一定把区间拆成了若干段,对这些段递归计算。
时间复杂度:$O(n\log n)$
其实此题还有另一个结论:$\sum_{i=1}^n \max(0,d_i-d_{i-1})$,其中 $d_0=0$。
这个结论可以用递推证明,令 $f_i$ 表示填好前 $i$ 个区域所需的最短时间。那么我们对当前的 $d_i$ 分类讨论。
- 如果 $d_i\le d_{i-1}$,那么我们可以在填 $d_{i-1}$ 时顺便把 $d_i$ 填好,即 $f_i=f_{i-1}$。
- 如果 $d_i>d_{i-1}$,那么我们需要单独把 $d_i$ 高出的部分填上,即 $f_i=f_{i-1}+(d_i-d_{i-1})$。
由于我们需要的只是 $f_n$,所以就是上面那个式子了!
时间复杂度:$O(n)$
Code
第一种做法:
1 |
|
第二种做法:
1 |
|
货币系统
Description
有 $n$ 种不同面额的货币,第 $i$ 种货币的面额为 $a_i$,每种货币都有无限张,我们把这个货币系统记作 $(n,a)$。两个货币系统 $(n,a)$ 和 $(m,b)$ 是等价的,当且仅当对于任意的非负整数 $x$,要么能被两个货币系统都表示出来,要么两者都无法表示。
现在给出一个货币系统 $(n,a)$,你需要求出一个货币系统 $(m,b)$ 使得两者等价并最小化 $m$。
本题 $T$ 组数据。
数据范围:$1\le T\le 20$,$1\le n\le 100$,$1\le a_i\le 25000$
Solution
通过感性证明可以得到:新的货币系统内的货币一定属于原来的货币系统。
那么我们把货币从小到大排序,如果某个货币 $a_i$ 能被之前的货币表示出来,那么这个 $a_i$ 一定是多余的;否则 $a_i$ 一定属于新的货币系统。这个过程显然用一个完全背包就能实现了!(我在考场竟然写了一个 $\text{bitset}$ 优化的多重背包 QAQ)
时间复杂度:$O(n\cdot a_i)$
Code
1 |
|
赛道修建
Description
C 城要举办赛车比赛,需要在城内修建 $m$ 条赛道。C 城有 $n$ 个路口和 $n-1$ 条适合修建赛道的双向通行的道路,第 $i$ 条道路的长度为 $l_i$,所有路口都直接或间接连通。一条赛道由一组互不相同的道路组成,满足从起点出发依次经过这些道路到达终点。一条赛道的长度等于经过的各道路的长度之和。为保证安全,要求每条道路至多被一条赛道经过。
你的任务是设计一种赛道修建的方案,使得修建的 $m$ 条赛道中长度最小的赛道长度最大。
数据范围:$2\le n\le 5\times 10^4$,$1\le m<n$,$1\le l_i\le 10^4$
Solution
首先,看到“最大化最小值”可以想到二分答案 $ans$,那么将问题转化为:是否可以选择 $m$ 条长度至少是 $ans$ 的链。
考虑以 $u$ 为根的子树,最优解中有一些链完全在子树内部,还可能有一条链经过 $u$ 向子树外扩展。在子树内部的链的数量相同的情况下,我们肯定要尽量使可以往上扩展的链尽可能长(如果没有,那么这个长度就是 $0$)。
我们用 $f(x)$ 表示子树 $x$ 内部最多有多少条链,$g(x)$ 表示当子树内部链最多时,剩下的以 $x$ 结尾的链最长是多少。
考虑怎么用这两个值进行转移。对于 $u$ 的每个孩子 $v$,它为 $u$ 提供了长度为 $len(v)=g(v)+w(u,v)$ 的可以用于拼接的链,以及 $f(v)$ 的答案。如果 $len(v)\geqslant ans$,那么可以直接选择这条链并使答案 $f(u)$ 增加 $1$。否则我们可以选择两条满足 $len(v_1)+len(v_2)\geqslant ans$ 的链进行匹配并使答案 $f(u)$ 增加 $1$,接下来我们分析选择两条链匹配的问题。
我们要使得 $len(v)$ 匹配的对数最多。这显然就是一个双指针贪心的过程。但是我们还要使剩下的一条链尽可能长。那我们稍微改变一下算法:每次考虑 $len$ 最小的 $v$,并找到最小的 $len(v’)$ 满足 $len(v)+len(v’)\geqslant ans$(如果不存在就不考虑 $v$ 这条链),把 $v$ 和 $v’$ 这两条链进行匹配。这样这样把所有的 $len(v)$ 匹配完之后,可以证明 $g(u)$ 就是未匹配的最长的链。
时间复杂度:$O(n\log n\log T)$(其中 $T$ 为二分答案的值域,上界为 $\sum l_i$)
Code
1 |
|
旅行
Description
X 国有 $n$ 个城市,之间有 $m$ 条双向道路(不存在重边和自环,保证所有城市直接或间接连通)。小 Y 的旅行方案如下:任意选定一个城市作为起点,然后从起点开始沿道路走向一个没有去过的城市,或者沿着第一次访问该城市时经过的道路后退到上一个城市。在小 Y 的旅行方案中,每个城市都要被访问到。
小 Y 在第一次访问某个城市时,会记录下这个城市的编号,这样会形成一个长度为 $n$ 的序列,你需要求出字典序最小的序列。
数据范围:$1\le n\le 5000$,$m=n-1$ 或 $m=n$
Solution
由于每次访问一个新的点(除了起点),一定会经过一条新的边。除了起点,我们一共要访问 $n-1$ 个点,那么会有 $n-1$ 条边,所以最终的路径会形成一棵生成树。
我们对 $m=n-1$ 和 $m=n$ 的情况分开考虑。
-
当 $m=n-1$ 时
我们一定选择编号为 $1$ 的点作为起点,可以发现题目中的限制等价于对原图进行 $\text{DFS}$,形成的序列就是 $\text{DFS}$ 序,我们要让 $\text{DFS}$ 序字典序最小,那么只需要对儿子节点排序,按照编号从小到大访问即可。
时间复杂度:$O(n\log n)$
-
当 $m=n$ 时
根据之前证明的结论,我们可以知道一定有一条边不会被经过。那么我们只要枚举这条边。如果剩下的是一棵树,那么就按照树的方法进行 $\text{DFS}$,在所有情况中取字典序最小的作为答案。注意:并不是每次 $\text{DFS}$ 都需要进行排序,我们可以事先对每个节点的相邻节点排序。
时间复杂度:$O(n^2)$
然而这题是可以优化到 $O(n\log n)$ 的!
如果我们把环单独考虑,那么在每棵树上肯定是正常走,走到环上之后肯定会走较小的那一条边。因此我们可以把环找出来,很容易确定下来在环上的走的方向,接下来就可以直接 $\text{DFS}$ 求解了!
Code
第一种做法:
1 |
|
第二种做法:
1 |
// 我也不会写啊 QAQ |
填数游戏
咕咕咕
保卫王国
咕咕咕