OI 中一类限制性问题的思考方法

前言

在算法竞赛中,有一类常见的题目,其形式多类似于:

  • 求满足……的元素数量或最优权值。

  • 给定元素,可以进行……的操作使元素发生变换,求最终可能的元素的种类数或最优权值。

注意这里不认为所谓“任意重排”等等是操作,因为这属于计数的部分。

对于第一种题目,需要考虑的元素所满足的要求被直接形式化地给出,绝大多数难度不算特别高,下面称这种限制为“定义限制”。

而第二种题目,给出的操作形式可能较为复杂,对元素的影响也可能较为复杂,所以有时候顺着题意是走不通的,称这种限制为“生成限制”。

这里主要记录面对这种题目如何能快速且准确地找到最可能正确的思维路径。

定义限制

直接处理

当题目给出的限制已足够简单时,我们可以直接进行计算。

最简单的例子就是 \(\text{LIS}\),求的是满足上升的子序列的最大长度,由于限制足够简单,我们可以直接 \(\text{DP}\)。

转化

有时题目限制比较难以处理,并不能直接采用贪心、\(\text{DP}\) 或者数据结构去解决。

需要先将其转化成其他形式才能计算。

同类分段

令 \(S_{l,r}\) 表示区间 \([l,r]\) 所有数构成的集合。

原本对于区间 \([l,r]\) 合法的限制是 \(\exists m,S_{l,m}=S_{m+1,r}\)。

这个可以等价转化为 \(\exists m,S_{l,m}=S_{l,r},S_{m+1,r}=S_{l,r}\)。

进一步地,可以推出一个更简单的 \(m\) 固定的限制,然后用数据结构解决。

找必要条件

某些较难的题目中,顺着原题给出的限制进行等价转化难以推出更加简单的限制。

这时我们可以找原限制的必要条件,有时多找几个必要条件组合起来就是原限制的充要条件了。

找条件的过程中可以结合满足当前条件却不合法的反例去推出新条件,也可以打表等等。

\(\text{Permutation Transmission}\)

首先,若存在相同的行必然无解。

那么先转换计数对象,显然不同的行排列对应的数组也一定不同,故直接对合法的行排列进行计数即可。

若直接根据题意,可得合法条件是矩阵对应的数组是 \(1\sim n\) 的排列,但这并不好计数。

将条件转化为:

  • 不存在相同列。

  • 不存在全 \(0\) 列。

  • 重排后第 \(i\) 行的 \(\text{popcnt}\) 恰好是 \(1\sim n\) 中第 \(i\) 位为 \(1\) 的个数。

这三个条件都是必要的,但是组合起来就是充要的了。

证明考虑到第三个条件本质上是保证了数组的总和恰好是 \(1\) 加到 \(n\) 的和。

生成限制

这类题目中有一个重要的特征是操作的任意性比较强。

模拟操作

通常适用于操作本身很简单的情况,本质上是聚焦于操作的过程。

直接将操作体现在了算法中,包括贪心地以某种方式进行操作,数据结构找到最优的操作方式,以及对操作过程进行 \(\text{DP}\) 等等。

\(\text{Navier–Stokes}\)

发现仅有最小周期的整数倍会导致算重。

直接考虑 \(\text{DP}\) 往后面拼接周期即可。

转化操作方式

一般来说会比较一眼,是那种出题人强行加上去的壳子。

有时候会伴随着统计对象的改变,比如原数组变为差分数组,对应的区间操作就变为单点操作。

简化操作流程

可能是比较罕见的方法,目前没有见过很多需要这样做的题。

关键在于尽管操作较为复杂,但到达所有合法元素的路径仅仅需要很少的步数或者小部分操作。

从而可以直接模拟操作。

\(\text{Knocker}\)

可以证明对于所有的可达序列,每个数都只会经历一次有效取模,且这一次取模的模数一定至少是原数的一半,故可以视作减法。

然后直接对序列做 \(\text{DP}\)。

转为定义限制

在较难比赛中极常见的技巧,但也比较单一,往往是部分难题的前几步。

当操作过于抽象时,直接顺着考虑几乎走不通,这时需要刻画出合法(即通过给定操作可达)元素所需要满足的充要条件。

找这些条件时,一般也是先写出若干显然的必要条件,然后再组合起来,假设它们是充要的,看看能否找到反例,如果能,就根据反例写出新的必要条件。

一直重复,直到找不到显然反例为止,过程中可以进行打表。

染色结果

对操作可达的所有 \(c\) 计数。

故直接考虑 \(c\) 合法的条件:

  1. 相邻点颜色不同。

  2. 颜色为 \(c\) 的点,其周围必须要有 \(0 \sim c-1\) 的每一种颜色。

当然,本题的难点不在这里,后面关于 \(\text{mex}\) 的性质才是难发现的地方。

🚇

进行任意次连边操作后选择首都,求最优的 \(d\) 数组。

直接考虑 \(d\) 数组合法的条件。

由于是最短路数组,那么显然有 \(\forall i,d_i \geq 0\),且 \(\exists i,d_i=0\)。

其次,还需满足 \(\forall i,|d_i-d_{(i+1)\bmod n}| \leq L_i\)。

进行构造可以得到这两条是充分的。

最优化

数组 \(a\) 合法的充要条件:

钦定 \(a_0=a_{n+1}=V+1\),对于任意的极长等值段 \((l,r,v)\),一定满足下面两条之一:

  1. \(r-l+1 \geq k\)

  2. \(\min(a_{l-1},a_{r+1})<v\)

数数题

\(\text{DP of DP}\)

当无法找出简单的等价定义限制时,可以观察对于已知结果,能否通过 \(\text{DP}\) 的方式进行判定。

如果可以,且这个 \(\text{DP}\) 的形式足够简单,就可以使用 \(\text{DP of DP}\) 的技巧解决外层的计数或者最优化问题。

局部函数

后话

以前总把这些东西一句话概括为“找性质”,可真正在赛场上才发现如果脑子里只有“找性质”三个字的话,常常会遗漏思维树上的一些分支。

向高天祈祷,再向远海寄托愁思。

高天或许不语,但波浪会带给你回信,如一声水妖的咏叹。

posted @ 2026-09-22 19:27  jr_zch  阅读(29)  评论(9)    收藏  举报