专栏文章

攻破难题的过程

算法·理论参与者 20已保存评论 24

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
24 条
当前快照
1 份
快照标识符
@mkbet9bj
此快照首次捕获于
2026/01/13 01:01
上个月
此快照最后确认于
2026/02/19 01:18
12 小时前
查看原文
发现前两篇文章太胡扯了,写出来没啥用。于是写点实在的。
下文说的难题不一定很难。

一些例子

举一下 CSP/NOIP2025 的例子:

清仓甩卖

  1. 我们需要观察到最优策略可以被反悔贪心求出的性质
  2. 我们需要刻画反悔贪心涉及到的关键元素。做到这一步可以获得 O(n3)O(n^3)O(n4)O(n^4) 的复杂度。
  3. 我们需要化简组合式子,并做到 O(n2)O(n^2) 的复杂度。
这对应了三种没有想出本题的情况:
  1. 没有观察到 / 观察错误第一步性质。
  2. 没有成功刻画 / 刻画错误第二步。
  3. 没有化简成功第三步的式子。
不得不承认的是,我推出了第三步并写完代码后,一直把精力集中在寻找代码本身的问题上,没有发现刻画错了一个细节。这样就很惨了。
这说明在长链思考中,上层的正确是下层的基础。

员工招聘

  1. 关键性质:一个人是否逃掉当天的面试,只在于之前不录取的人数。这使得我们可以按照不录取的人数划分阶段
  2. 设计 dp:设计 fi,j,kf_{i,j,k} 表示目前是第 ii 天,不录取了 jj 个人,此时耐心 j\le j 的人中,有 kk 个已经被录取。
  3. 规划转移:严格按照 jj 分层转移会获得 O(n5)O(n^5)8080 分的好成绩,别问我怎么知道的。如果按照 ii 转移可以 O(n3)O(n^3)
本题显然比上一题要清晰一些,但是需要选手熟悉一些排列计数问题。
其中最难的还是第一步,看起来没多少人像我一样炸在最后一步

树的价值

本题有很显然的递进关系。可以发现 O(n3)O(n^3) 的 dp:
O(n3)O(n^3)
使用延后贡献的思想。设计状态为 fi,j,kf_{i,j,k} 表示树上第 ii 个点的子树内,填数使得这个子树中节点权值集合的 mex\mathrm{mex} 等于 jj,且还剩下 kk 个数没填写。子树 ii 的总答案。
对于转移,做树形背包,对子节点 vv 转移 fi,max(j1,j2),k1+k2fi,j1,k1+fv,j2,k2f_{i,\max(j1,j2),k1+k2} \leftarrow f_{i,j1,k1} + f_{v,j2,k2}。其中 max(j1,j2)\max(j1,j2) 需要 max 卷积支持。
可以获得 4848 分。
接下来是一个可以想到的钦定思想:
O(nm2)O(nm^2)
考虑优化,我们定义一条边 (i,v)(i,v) 是实边,则这个点 iijjvv 转移,其余边定义为虚边。
显然若确定了实边,类似树链剖分,实边形成了若干条链。考虑再次计算每一个点对答案的贡献,容易发现,这个点会存储一点“能量”,并且向上传递。
ii 一直向上跳,当其到达某一个点(它的祖先)之后可以选择“使用”这点能量,对这个点一直到第一次出现虚边的位置增加一条贡献。
容易发现 ii 到根的路径上最长的相邻两个虚边的距离(根和 ii 点特例)即为 ii 对答案的贡献。
如果直接设计 fi,j,kf_{i,j,k} 为钦定 ii 点到根的路径上最长虚边距离为 jj,当前 ii 向上的最近虚边的距离是 kk,只考虑子树 ii 内的总答案。
仍然从下往上 dp,但是时间复杂度为 O(nm2)O(nm^2)
可以获得 7676 分。
接着是一个状态优化:
状态优化
拆分 dp 状态为 fi,jf_{i,j}gi,jg_{i,j}。重新开始定义。
fi,jf_{i,j} 为强制钦定 ii 点是我们剖分的链头,上方最长虚边距离为 jjii 子树内答案。
gi,jg_{i,j}ii 点是一条链中的第 jj 个部分,认为 ii 点离上方最近虚边距离已经足够长(就是 jj 足够大),ii 子树内的答案。
fi,jf_{i,j} 需要枚举 ii 子树内的其中一个点,其到 ii 距离为 jj,记这个点为 lliill 的路径是实链。
则实链上点的其他儿子 vv 是虚边,这些儿子的答案由 fv,jf_{v,j} 给出。
ll 点的贡献为 gl,jg_{l,j}
此时理论枚举量已经得到 O(nm)O(nm)。问题在于如何快速计算这么多权值的和。
后面使用长链剖分优化或者直接树状数组就可以通过了。

从出题的角度看

难题的迷惑性

解题像走迷宫。如果凭借直觉就能探索到正确的路,那么这一步就无法坑害做题人。

难题的复杂性

解题像走迷宫。如果路上没有难以推导,需要耐心才能跨过的障碍,那么只需要灵光一闪就如顺水行舟般做完整个题了。

刻意构造

出题人会寻找难以想到的转化,然后编一个题出来,把已有的模型做巧妙的转化。
这种转化一般是一个 trick。

妙手偶得

出题人通过各种手段从头开始编一个题出来,然后自行探究。

二者兼备

可能出题人编的题不好 / 不可做,然后再通过刻意构造的方式修改?
出题人通过探究自己的题目,为其加强 / 推广?

一种分析

(我写完了才看到这个)
LCA 的博客中:题目强度的向度。
但是我是还没退役的(希望不是快退役的)OI 选手,所以对我来讲,“冷度”和“科技度”并不是很重要。

“探究”是什么

一种理想化的学习方式

一种目标不是为了完成任务的学习方式。
探究不指向直接的积累,如:“看到什么,就要想到什么”这种套路。
探究的重点在于,研究模型并且尝试加以推广。
很多题目都是在探究中被出出来的。
探究的动力来源于对未知的好奇,也正因如此,它比较理想化。
对题目的兴趣因人而异,这也于“天赋”有关,当然我不是天赋哥,所以这里说的“探究”比较理想化。
接下来说的东西和“做题 / 比赛方法”有重叠。

描述 / 刻画是一种探究

描述 / 刻画你所要探究的问题。
字面意义上讲,给你的问题画一幅画。
有很多描述的方式,比如用数学语言描述你的问题。
让我被数学语言所震撼的两个题解,集合绝对防御
把要解决的问题清楚的讲出来也是一种简单的描述。
用简单的模型把问题更好的讲出来是一种描述 / 刻画。
双序列拓展把题目刻画了在网格上移动的问题。
网络流题目也是建模思想。

推理是一种探究

数学公式的推式子,或者是一些纯粹的把戏,都是推理的体现。
推理无处不在,而且也有很多很直觉,很简单的推理。
如下
首先考虑怎么知道所有 bib_i。我们作 bb 的前缀和 sis_i。相当于知道 s1,s2,...,sns_1,s_2,...,s_n 就可以还原了。
则问 [l,r][l,r] 可以知道 srsl1s_r-s_{l-1}。发现相当于知道 srs_r 就可以知道 sl1s_{l-1},反之亦然。
连一条双向边 (r,l1)(r,l-1),显然我们是知道 s0s_0 的,问题转化为 00 可以到所有点,也就是图连通,最小的话就是图的最小生成树。
问题变成最小生成树,在 (l,r)(l,r) 之间连边代价是 gcd(al+1,...,ar)\gcd(a_{l+1},...,a_{r})
文化课学习中最常用的思考方式也是推理。

观察 / 实践是一种探究

观察可以发现性质。性质可以简化 / 弱化我们的问题。
树的遍历运用了“可以生成某一棵树的根节点是一条链”这一性质。这基本是通过观察得到的。
这可能和实践有很大的重叠。但是观察重点在于直接看出性质是啥,猜测 / 实践主要是一个动态过程(边猜测边验证)

联想是一种探究

回响形态中,原题可以转化成回文串计数问题,使用马拉车解决。
结合一下文化课学习。函数大题中,构造一个我们需要的函数需要对其进行联想。
这种问题不仅需要刻画,而且需要把刻画后的问题与另一个已知可做的问题联想在一起。

猜测 / 实践是一种探究

对模型进行实践(手玩或者是模拟算法,打表)可以帮助我们进行观察。
这是探究的一种很常规的表现方法。
猜测辅助实践。猜测的方向和个人经验相关,猜测和联想又有很大关系。

与上述“难题”的关系

对症下药。
对于“刻意的”题目,注重联想。
对于“adhoc”题目,注重寻找性质。
对于“构造”题目,注重实践。
难以理解的问题,进行刻画。

探究的缺点

探究法太激进,人脑可能会出错,接下来对两种情况进行修正。
失败陷阱:之前讨论过,你所知道的一条思维道路失败不一定是真的失败。
成功陷阱:之前讨论过,你所知道的一条思维道路成功不一定是真的成功。(也就是想假了)

怎么获得探究的动力

我刚才又开始胡扯了,那么怎么获得探究的动力呢?
不知道啊,感觉我这几天状态都不是很好,比赛在一直爆零,有没有人帮我增强一下动力 /ll。
纸上谈兵没有意义,更重要的是落实实践,可是最近模拟赛的难题都很难理解,那些过去的题又不知道怎么去改了。
可能我需要休息一下。
至少我还有一年,或者说,只剩一年了吧。。。

我出的几个题

如果直接说明的说服力不足,我决定举出我自己出的几个自我感觉良好的题的例子。

星命定轨

这个题可能刻意度比较大,有点引导做题人做不出来这个题的趋势才让这个题黑了。。。其实没那么难。
关键在两个性质。这些性质可以通过猜测 / 实践或者是观察发现。具体可以直接去看题解,我就不剧透了。

天阶梦游

这个题难度比较大。第一步就要用到刻画成数学语言的手法。后面更是连续的使用刻画和猜测。具体还是看题解吧不剧透。

演剧

这是很显然的手模题!通过猜测 / 实践就可以做出来了。需要一点耐心和注意力。

评论

24 条评论,欢迎与作者交流。

正在加载评论...