【做题记录】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\) 的大小关系:

  1. \(f_{i,j}\to f_{i+1,k}(j\ge k)\)

  2. \(f_{i,j}\to f_{i,j+1}(k>j)\)

总时间复杂度 \(O(n^2)\)

posted @ 2022-01-17 21:10  trsins  阅读(54)  评论(0)    收藏  举报