【做题记录】ARC068D Solitaire
-
\(\text{ARC068D Solitaire}\)
- 算法:dp
题目:
将 \(1\sim n\) 顺序加入双端队列(每次可加头可加尾),再删除(每次可删头可删尾),求有多少种删除序列,使得 \(1\) 是第 \(k\) 个被删的。
\(1\le n,k\le 2000\)。
题解:
这里是一个 \(O(n^2)\) 的做法,在这篇题解中有 \(O(n+q)\) 的线性做法。
考虑这个双端队列长什么样:应该是一个以 \(1\) 为分割点,左边是一个单调下降序列,右边是单调上升序列。
考虑删除的第 \(k\) 个点要是 \(1\),弹出时是选择两端中的一端弹出,拆开弹出的序列,一部分为前端弹出的数,另一部分为后端弹出的数,于是这两部分就是单调递减的,且前 \(k-1\) 个数中其中一个序列的最小值一定大于后 \(n-k\) 个数中的最大值。
然后因为在确定了 \(1\) 的位置后,之后随便删除,所以剩下的随便排序,有 \(2^{n-k-1}\) 种。
直接 dp:\(f_{i,j}\) 表示前 \(k-1\) 个数中前 \(i\) 个数,这些数的最小值为 \(j\)。
考虑下一个数 \(k\) 与 \(j\) 的大小关系:
-
\(f_{i,j}\to f_{i+1,k}(j\ge k)\)。
-
\(f_{i,j}\to f_{i,j+1}(k>j)\)
总时间复杂度 \(O(n^2)\)。

浙公网安备 33010602011771号