Akane Weekly #10(NOIP 历年题目)
Akane Weekly #10(NOIP 历年题目)
感觉没啥特别难的,很多难度虚高。
指有一些难得根本不会,先放一边。
1.P2668 [NOIP2015 提高组] 斗地主
看起来就很 Ad-Hoc 。这种题在考场上根本不敢开啊。
先写一个爆搜,发现只考虑同点数排的情况下可以不用爆搜,也就是说先考虑涉及不同点数的。
这样就可以过普通版本了,(很水)。
加强版就卡一下常,再加一个哈希剪枝(记忆化,如果当前状态搜过就跳过,哈希维护)即可。
2.P2679 [NOIP2015 提高组] 子串
把暴力的 DP 方程写出来之后优化一下。
朴素的 DP 式子:
时间复杂度 \(O(nm^3)\) ,期望得分 70 。
我们发现第二维度其实是一个从 \(j\) 逐个往前跳的过程,我们可以用一个前缀和来维护,时空复杂度 \(O(nm^2)\) ,期望得分 80 。(实际上只有70)
前缀和维护了之后, \(dp[i][j][k]\) 只会从 \(sum[i-1][j-1][k-1]\) 和 \(dp[i-1][j][k]\) 转移,我们可以把 \(i\) 这一维度给滚掉,时间复杂度 \(O(nm^2)\) ,空间复杂度 \(O(m^2)\) ,可以通过。
3.P2680 [NOIP2015 提高组] 运输计划
树链剖分模板题。
对于每一条边考虑它的答案,那么它的答案是 \(\max(E_1-w,E_2)\) 。
其中 \(E_1\) 是经过它的边的权值,\(E_2\) 是不经过它的边的权值,\(w\) 是边的边权。
相当于我们对于每一条边,要维护 \(E_1,E_2\) 。
现在我们考虑每一条路径对边的贡献,对路径上每一条边的 \(E_1\) 有一个路径长度的贡献,树剖即可。
考虑如何对路径之外的边贡献。
我们轻重链剖分之后,路径被剖分成至多 \(O(\log n)\) 块,那么不在路径上的也至多 \(O(\log n)\) 块,排序之后也可以用树剖维护。
时间复杂度 \(O(n\log^2n)\) 。
4.P2312 [NOIP2014 提高组] 解方程
考虑模意义下的等于即可。居然不卡模数。
这也能蓝?
5.P2296 [NOIP2014 提高组] 寻找道路
考虑限制,建反图求出哪些点到不了终点,这些点旁边的点就是不能再路径上的点,最短路即可。
6.P1967 [NOIP2013 提高组] 货车运输
疑似有些粘合了。
相当于找一条最大瓶颈路径。
考虑对所有起点,终点做这个问题,那么路径必然构成一棵树结构,也就是最大瓶颈生成树。
根据瓶颈树定理,我们只需要找最大生成,用 Kruskal 即可。
之后我们在树上求任意两点的路径上的最小值,用树链剖分即可在 \(O(\log^2 n)\) 时间回答询问。
时空复杂度 \(O(m\log m \alpha(n)+q\log^2 n)\) 。
我甚至感觉暴力能过?
7.P1966 [NOIP2013 提高组] 火柴排队
一旦要给数组排序,取逆,就会把我绕晕,破防了。
先写 \(60\) 分,暴力,跑过去 \(90\) ,含金量。
考虑两个数组对应数字排名相同时最优,让第二个变成第一个的顺序,按照这个进行排序,相当于我们要求新的第二个数组移动多少次才能变成第一个,即逆序对,树状数组求解即可,时间复杂度 \(O(n\log n)\) 。
8.P1979 [NOIP2013 提高组] 华容道
这种题目真的好烦,代补。
暴力枚举空白点,移动点搜索 \(O(qn^2m^2)\) ,大概 \(4e8\) ,题解区卡一卡都过了,老题是这样的。
考虑删掉没有用的状态,发现空白格子只有在移动点的上下左右时移动点才可以动,因此我们可以考虑只搜索这些状态,那么状态数只有 \(O(nm)\) 级别了。考虑当前状态是 \(dp[i][j][di]\) 表示在点 \((i,j)\) ,空白点在当前的上下左右 \((0/1/2/3)\) 最少要的步数,那么考虑如何向后转移,我们可以将当前点走到空白点,即有转移 \(dp[i][j][di]\rightarrow dp[i+dx[di]][j+dy[di]][fdy(di)]+1\) ,其中 \(fdy(di)\) ,表示 \(di\) 的方向逆。
当然,我们也可以改变空白格子的位置,由于只有移动格周围四个点有用,我们只需要考虑转移到除了其本身之外另外三个点即可,有转移
其中 \(d[x][y][di][z][w]\) 表示移动点为 \((x,y)\) 时将 \((z,w)\) 转移到 \((x+dx[di],y+dy[di])\) 的最小步数。
注意,这个移动时是不能动 \((x,y)\) 的。
那么初始状态就有四种,看一下要把空白格子移动到关键格子上下左右哪一个,再做 DP 即可。
这个 DP 满足最短路的式子,用一种你喜欢的最短路即可。
时间复杂度 \(O(n^2m^2+qknm)\) ,毕竟出题不卡 SPFA 。
9.P1600 [NOIP2016 提高组] 天天爱跑步
考虑对每个点进行考虑,有多少条路径对它有贡献。
发现有贡献的点,要求子树内起或终点有深度限制,按照 LCA 分成两段,推出式子之后用桶来维护即可,进入子树之前把答案记录一下,加一下贡献,再统计答案减去即可(套路),贡献变化用树上差分即可。
10.P3953 [NOIP2017 提高组] 逛公园
没看懂题解区的搜索为什么状态更新顺序是对的。
如果有 \(0\) 环且可以,且可以再规定步数要求内走到终点,一定无解。
我们将 \(0\) 环缩成点之后,所有以 \(1\) 为源点的最短路边会构成一个 DAG ,求出这个 DAG 的拓扑序,在拓扑序上 DP 即可。
DP 状态可以设计成 \(dp[u][i]\) 表示第 \(u\) 个点,路径长度为 \((dis[u]+i)\) 的方案个数。
对于有一条边 \((u,v,w)\) 如果满足拓扑序要求,有转移:
对于每一个大于 \(1\) 的强连通分量,将 \(dp[u][0]\) 设置成 \(-1\) ,用于判断无解。
最短路可以使用 dijkstra 算法,总时间复杂度 \(O(m\log m+k(n+m) )\)
可能有些卡空间。
这下图论大杂烩了。
11.P3960 [NOIP2017 提高组] 列队
首先我们先观察11#-16# 测试点:
相当于只有一行在用,即把一段区间左移,问第 \(k\) 个位置上的人。
将左移改成单点右移,每次找到答案之后将对应右移的位置改成答案,线段树维护区间有多少个位置有人,线段树上二分即可回答,时间复杂度 \(O(n+q\log(n+q) )\) 。
对所有数据尝试类似做法。
维护 \(n+1\) 个线段树,其中第 \(n+1\) 个用来维护最后一列。
每次询问,如果正好问最好一列,直接同上做。
否则,先同上取出这一行答案,然后再在最后一列的这一行之后的左移一位(同上转化成单点在右侧增加),
同时把新的这一行的最后一个数加入这一行的 vector 即可。
注意,初始的数不用加入 vector,如果答案在原来的位置内,直接计算输出即可。
用动态开点保证空间复杂度,时空复杂度 \(O(n\log n)\) 。
当然,你也可以直接使用万能的 splay,但我不会。
12.P3959 [NOIP2017 提高组] 宝藏
\(m\) 是假的限制。
\(abl[st][u]\) 表示当前状态为 \(st\) ,走相邻点完成点 \(u\) 的最少花费,若走不到,则为 \(-1\) 。
\(dp[st][d]=\min(dp[s][d-1]+\sum abl[s][u])\) 表示扩展到第 \(d\) 层,起点为 \(u\),当前选的点状态为 \(st\) 的最小花费。
再把 \(abl\) 预处理了,保证时间复杂度。
时间复杂度 \(O(n^23^n)\) 。
upd:确实很水。
14.P5020 [NOIP2018 提高组] 货币系统
维护每个值的可行性,只用维护到 \(\max{a_i}\) ,因为判断时只需要判断 \(a_i\) 是否可行。
对现有状态集合每一个状态可以加上 \(ka_i\) ,完全背包板子。
15.
代补。

浙公网安备 33010602011771号