五年高考三年模拟
csp2023
密码锁
30min ac 100pts
看到\(n \leqslant 8\),想到暴搜,但是如果是最劣的dfs,复杂度是\(O(k^n)\),其中\(k\)约为\(90\),难以承受,那考虑优化爆搜,发现只需要\(O(kn)\)即可。
消消乐
120min ac 100pts
我们发现如果直接对每个位置用栈匹配,会漏掉一部分贡献。这是开始入栈的位置导致的。因此不难想到对入栈位置进行枚举,但这样是\(O(n^2)\)的,难以承受.我们发现当两个字母可以匹配当且仅当入栈时栈中元素一致,因此可以用哈希记录并比较,但这样做需要一个map
,\(O(n\log n)\),依然不够优秀.我们考虑到dfs本身就是入栈出栈的过程,因此想到使用字典树,复杂度\(O(n)\),比较圆满.
结构体
90min ac 100pts
暴力模拟即可,不用管复杂度,数据范围很小。
种树
90min tle 60pts
120min ac 100pts
难以解决,因此考虑二分答案,我们可以用数学知识获得每个节点的最后期限,然后贪心解决。时间复杂度\(O(n\log^210^9)\),经过一些最优性优化达到\(O(n\log 10^9 \log n)\).
NOIP2023
词典
30min ac 100pts
采取贪心策略,对每个\(i\),只需要\(w_i\)的最小形式小于\(\displaystyle\min_{j\neq i}w'_j\),其中\(w'_j\)是\(w_j\)的最大形式,因此只需预处理\(w_i\)的最小形式,以及\(w_i\)的最大形式的最小值及次小值即可.
三值逻辑
60min ac 100pts
发现执行的过程可以暴力模拟,直接得到所有变量的初值和最终值的依赖关系,根据初值和最终值相等,建立带权并查集.我们发现\(Unknown\)所在子树一定均为\(Unknown\),有权值依赖冲突的子树一定全为\(Unknown\).
双序列拓展
不会 0pts
我们先考虑朴素dp,设\(f_{i,j}\)为是否存在一种方案使得\(F\)以\(A_i\),\(G\)以\(B_j\)结尾,且是合法的,不难发现其有状态转移方程:
考虑其实际意义,相当于将\(f\)绘制为一个矩阵后,满足\(A_i < B_j\)的点\((i,j)\)是联通的,考虑是否有一条路径,使得\((1,1)\)到\((n,m)\)联通.
我们发现,如果\(a_i \geqslant \max b_j\)或者\(\min a_i \geqslant b_j\),则有一整行/列不连通,反之则有一个十字架联通.递归处理左上角和右下角即可.
天天爱打卡
不会 0pts
发现如果一个状态的末尾可以跑步时,状态有后效性,因此设\(f_i\)表示在\(i\)的时刻摆烂可以获得的最大分数.因此有转移方程
我们发现状态转移方程中可以提出来有关于\(j\)的部分,想到可以对其维护最值,其中任务奖励部分需要动态修改,我们发现,当\(i > r_j\)时,可以开始考虑活动\((l_j,r_j,v_j)\),此时,如果从\([1,l_j)\)的位置转移,答案就会增加\(v_j\).与此同时,每次处理好一个\(f_i\),就应该更新数据结构以供后面转移.因此我们发现该数据结构需要支持区间加,单点修改,查询区间最值.因此选择使用线段树维护.
csp2022
策略游戏
40min ac 100pts
我们发现两个人是有取数先后的,因此可以从第二个人的最优解入手.有序列\(a_{l_1...r_1},b_{l_2...r_2}\),A取了数\(a_i\),B要让乘积最小,因此当\(a_i > 0\)时,B会取\(b_{min}\);\(a_i < 0\)时,B会取\(b_{max}\);\(a_i = 0\)时,得分为\(0\).这样,我们对每个\(a_i\)都确定了B所去的数,分三种情况讨论:
-
\(a_i>0\),得分为\(a_ib_{min}\),A要使得分最大,而\(b_{min}\)是固定的,因此贪心的选择\(a_i\):
- \(b_{min}<0\),选择最小正数.
- \(b_{min}=0\),得分为\(0\).
- \(b_{min}>0\),选择最大正数.
-
\(a_i<0\),得分为\(a_ib_{max}\),A要使得分最大,而\(b_{max}\)是固定的,因此贪心的选择\(a_i\):
- \(b_{max}<0\),选择最小负数.
- \(b_{max}=0\),得分为\(0\).
- \(b_{max}>0\),选择最大负数.
-
\(a_{i}=0\),得分为\(0\).
只需用st表维护最值,分类讨论找最大值即可.
假期计划
90min wa 90pts
100min ac 100pts
发现环上除起点外只有四个点,而\(n=2500\),枚举四个点是不能接受的,但枚举两个点\(O(n^2)\)是可以接受的.我们发现枚举起点出发第一个点是有后效性的,贪心没有正确性,因此我们考虑枚举第二个和第三个点,此时我们可以贪心的选择同时与第二个点,与起点联通的权值最大的点,此时无后效性,贪心有正确性.因此,我们预处理邻接矩阵\(G_{i,j}\)表示\(i,j\)连通.发现folyd求邻接矩阵\(O(n^2k)\)无法接受,我们考虑求最短路,由于边权只有1,使用0/1dfs即可.复杂度\(O(n^2)\).这样的话,就可以得到与点\(i\)联通的且与起点联通的点权最大点\(f_i\),这样我们枚举得到\(u,v\),dp得到环\((f_u,u,v,f_v)\),由于可能重复,因此我们需要找到\(f_i\)的前三优的解.这样的话,经过一些重复check即可找到最大值.复杂度\(O(9n^2)\).
NOIP2022
种花
30min wa 10pts
30min ac 100pts
我们发现用乘法原理计数时,很重要的参数就是每个点向右,向下最大延伸多少格\(f_{i,j},g_{i,j}\),可以在\(O(nm)\)内预处理出来.与此同时,我们发现枚举字母左上角的复杂度是可以接受的,但这要求我们在\(O(1)\)时间内对每个点做出答案.我们发现每个点对答案(字母C
)的贡献是\(\sum_{m=i+1}^{i+g_{i,j}}f_{i,j}f_{m,j}\),发现这个信息可以使用前缀和维护,因此总复杂度\(O(mn)\).
建造军营
不会 0pts
发现环上选的点是无懈可击的--边双连通分量中的边都是可选可不选,因此考虑缩点.
考虑树上dp,我们考虑如何把方案分给每一个点,只需要按每个方案中深度最小的点分配即可,因此我们考虑如何在一棵子树中解决问题,计入答案时将方案数乘以子树外所有边的情况即可.
我们发现在转移时,如果一个点有多个子节点,那me我们考虑将父节点加前\(i\)棵子树的答案转移给前\(i+1\)棵子树,而第\(i+1\)棵子树选的时候前面的子树可选可不选,因此答案转移不但和选父节点\(u\)及其前\(i\)棵子树的方案数\(f_{u,i}\)有关,还和父节点和前\(i\)棵子树都不选的方案数\(g_{u,i}\)有关.因此我们要设计两个状态转移方程.如果设点\(u\)中蕴含着\(V_u\)个点,\(E_u\)条边,那么有:
csp2021
廊桥分配
40min ac 100pts
我们发现通过扫描可以得到每个航班有廊桥的最小分配廊桥数量,进而预处理出每个廊桥数量所对应的有廊桥航班数,这样可以解决问题.
括号序列
130min ac 100pts
发现\(n \geqslant 500\),\(O(n^3)\)是可以接受的,考虑区间dp.?
就是万能的一个位置,所有符号均可匹配.我们发现连续的对转移是很重要的,因此预处理每个位置向右的极大序列长度.我们发现转移形式有以下几种:
- ()
- (S)
- AB
- ASB
- (A)
- (AS)
- (SA)
暴力转移的话,这些转移大多数都可以在\(O(n)\)内转移,可以接受,但是ASB需要\(O(n^2)\)但是发现他是\(\prod x_iy_j\)的形式,前缀和优化至\(O(n)\).
最后考虑贡献重复问题.我们不难证明,一个串不能被表示为以上列举出的两种不同形式,除了AB和ASB形式.
我们钦定ASB对答案作出贡献所对应的串,若A能被拆为MN,则贡献按AB计算,若B能被拆为MN,则贡献按ASB计算.
我们考虑一个串AB,若A能表示为MN形式,则有划分MN/B,M/NB,有重复贡献,因此钦定A不能表示为MN.考虑一个串AB,若A能表示为MSN形式,则串可以划分为MSN/A,M/S/NA,两种贡献,因此钦定A不能表示为ASB.
考虑出一个串ASB,若A能表示为MSN形式,则有MSN/S/B,M/S/NSB,因此钦定A不能表示为ASB形式.若A能表示为MN形式,则有MN/S/B,M/NSB,因此钦定A不能表示为AB.
综上所述,在AB和ASB转移中,A均不能由AB/ASB得到.因此额外转移\(g_{l,r}\),记录\(l...r\)除AB,ASB以外的方案数.
回文
不会 0pts
我们发现,可以枚举第一次取左面还是右面,假设取了最左边,我们发现,如果\(a_1=a_i\),那么我们在序列只剩\(a_i\)之前不能操作\(a_i\),因此\(a_i\)左侧只能从左向右取,右侧只能从右向左,这样就得到了两个栈,我们发现做后取出的一定在两个栈底中的一个,因此我们可以贪心的选取左边栈的栈顶与两个栈底匹配,都不匹配就找右栈顶,再不匹配就返回无解.
NOIP2020
排水系统
40min wa 60pts
40min ac 100pts
拓扑排序后dp即可,这道题需要用gcd/lcm模拟约分过程
卡__int128
.
字符串匹配
60min wa 56pts
60min ac 100pts
要求分割\(S=(AB)^iC\),使得\(F(A)<F(C)\).可以枚举一个\(AB\)的截止位置,用kmp求解\((AB)^i\)的最大拓展位置,发现每多一个\(AB\),\(F(C)\)呈周期性变化,周期为\(2\),因此分奇数偶数两种情况统计.发现可以预处理维护前缀\(F(A)\),后缀\(F(C)\),此时只需在可接受的时间内求出满足条件的\(A\)个数即可,使用权值树状数组记录每个\(F(A)\)的出现次数,总复杂度\(O(n\log n)\)
csp2020
儒略日
130min wa 60pts
140min ac 100pts
日历计算.
在此对出题人致以崇高的敬意.
动物园
20min ac 100pts
考虑到一对多映射关系,而且不会有两个映射到同一元素,因此出现过的bit一定可以随便选,没有约束的bit可以随便选,其余bit均不能随便选.
csp2019
格雷码
20min ac 100pts
按每一个bit由高到低依次确定即可.
括号树
60min ac 100pts
前面一道题的弱化版,这道题只需要把dfs栈写出来就好.再栈的每个长度上记录好dp信息,这道题没有重复贡献问题.
NOIP2018
货币系统
ybtoj上有这道题,类似背包dp.