题解:P12880 [蓝桥杯 2025 国 C] 数字配对
这题真不是黄题吧。
题目要求在序列 \(A=\{a_1,a_2,\dots,a_n\}\) 中选出尽量多的下标对 \((i,j)\) 使得 \(i<j\) 且 \(a_j-a_i=1\),每个元素只能使用一次。
显然,难点在于既要满足数值差为 \(1\),又要保证下标严格递增。将同值元素的下标按升序集中存放,记第 \(v\) 值的下标序列为 \(P_v\)。对相邻两值 \(v\) 与 \(v+1\) 分别维护指针指向当前最右侧尚未配对的下标。始终比较 \(P_v\) 与 \(P_{v+1}\) 的末尾元素:若 \(P_v\) 的下标仍然小于 \(P_{v+1}\) 的下标,就立即将这二者配成一对并同时左移两个指针;否则只能左移 \(P_v\) 的指针。
这样做相当于在两条升序链上求“最长不交叉匹配”(就是求在不允许线段交叉的前提下能画出的线段最多是多少),可用交换论证证明最优:倘若最优方案中存在交叉形如 \((p,q)\)、\((p',q')\) 且 \(p<p'<q<q'\),交换得到 \((p,q')\)、\((p',q)\) 亦合法且不减答案,因而所有交叉都可消解到该贪心结构。
实现的具体流程可以这样理解:先整遍扫描原序列,把每个元素的下标依出现先后写入数组,同时用一个计数表记录每个值出现了多少次。扫描完毕后,对这张计数表做前缀和,就能算出每个值在数组中的起始坐标,于是同值元素的下标会自然排成一段连续区间,相当于给每个数字建了一个紧凑的下标桶。配对阶段,我们只在这些区间里顺着指针向左移动;每个指针只会离开当前位置一次,所以整体移动次数不超过 \(n\)。
时间复杂度 \(O(n+\max a_i)\)。

浙公网安备 33010602011771号