[NOI2019] 机器人

\(n\) 个柱子从左往右排成一排,第 \(i\) 个柱子的高度为正整数 \(h_i\)。

有两个机器人,起点均为 \(s\) 号柱子。机器人只能在相邻的柱子之间移动。

\(1\) 号机器人会一直向左移动,但他无法移动到高于 \(s\) 的柱子。

\(2\) 号机器人会一直向右移动,但他无法移动到不低于 \(s\) 的柱子。

已知 \(h_i \in [A_i,B_i]\),求不同正整数序列 \(H\) 的数量,使得:

  • 对于所有的起点 \(s\),设 \(1\) 号机器人移动的距离为 \(x_1\),\(2\) 号机器人移动的距离为 \(x_2\),有 \(|x_1-x_2| \leq 2\)。

结果对 \(10^9+7\) 取模。

\(1 \leq n \leq 300\),\(1 \leq A_i,B_i \leq 10^9\)。


先考虑如何 check 序列 \(H\) 是否合法。

我们不妨先找到最高的柱子,若有多个柱子高度相同,取最靠右的柱子。

不妨记该柱子的编号为 \(s_0\),显然有如下性质:

  • \(s=s_0\) 时,\(1\) 号机器人的终点为 \(1\) 号柱子,\(2\) 号机器人的终点为 \(n\) 号柱子。

  • \(s < s_0\) 时,\(2\) 号机器人无法移动到 \(s_0\)。

  • \(s > s_0\) 时,\(1\) 号机器人无法移动到 \(s_0\)。

不难发现,\(s = s_0\) 时,\(x_1 = s_0 - 1\),\(x_2 = n - s_0\)。

若 \(s_0\) 不满足条件,则 \(H\) 也就不合法了。

若 \(s_0\) 满足条件,考虑 \([1,s_0 - 1]\) 和 \([s_0 + 1,n]\) 两个区间是独立的,递归下去即可。

考虑这样 check 的时间复杂度,容易发现满足条件的 \(s_0\) 一定在当前区间的中间位置附近。

也就是说,\(T(n) = 2 T(\dfrac{n}{2}) + O(n)\),得到 \(T(n) = O(n \log n)\)。


我们知道了如何 check 后,考虑将其应用到 dp 上。

我们设 \(dp_{l,r,k}\) 表示区间 \([l,r]\) 内的最大值为 \(k\),对应的合法序列种数。

考虑枚举 \([l,r]\) 内满足条件的 \(s_0\),此时的转移式:

\(dp_{l,r,k} \leftarrow dp_{l,r,k} + (\sum\limits_{k_1 \leq k} dp_{l,s_0 - 1,k_1}) \times (\sum\limits_{k_2 < k} dp_{s_0 + 1,r,k_2})\)

因为 \(s_0\) 只有 \(O(1)\) 个,所以复杂度是 \(O(n^2 V^2)\) 的。

加上前缀和优化,就是 \(O(n^2 V)\) 的。

然而这样会产生很多无用状态,事实上根据上面分治做法的思想,有用的状态数不会太多。下文中记其为 \(m\),大概是 \(O(n \log n)\) 级别的。

也就是说,我们加个记忆化搜索,就可以做到 \(O(mV)\)。


我们观察上面的转移形式,大体上我们需要维护值域上的偏序关系。

我们不妨进行猜测,\(dp_{l,r}\) 是关于 \(k\) 的分段函数,每一段都是多项式。

你考虑对于 \(dp_{i,i}\) 是常数,也就是说 \(dp_{i,i}\) 的前缀和是一次多项式。

不妨猜测 \(dp_{l,r}\) 的前缀和是 \(r-l+1\) 次多项式,考虑证明。

dp 时,对于长度为 \(x\) 的区间 \([l,r]\),会拆成两个长度为 \(x_1\) 和 \(x_2\) 的区间,满足 \(x_1 + x_2 + 1 = x\)。

也就是说,将两个区间的前缀和相乘,\(dp_{l,r}\) 是 \(x-1\) 次多项式,其前缀和就是 \(x\) 次多项式。

而分段的情况容易处理。我们发现,值域分成的段数只会有 \(O(n)\) 段,每段只需要计算 \(O(n)\) 个点值。

posted @ 2026-01-04 13:25  Oken喵~  阅读(28)  评论(0)    收藏  举报