「JOI Open 2016」摩天大楼
题目难度:USACO P/省选
好像是暑假之前在 KarL05 推荐给我的dp博客里面看到的题目,但是因为太懒一直没有做,现在凭不完整的记忆把正解重新写出来。
思路:
估一下复杂度必然和 \(N,L\) 有关,并且题目要求带限制的排列数,不难想到解法应该是某种dp。由于要求 \(A\) 中一些数差值的和(下文记为费用),不妨先将 \(A\) 数组排序。接下来,考虑如何去掉绝对值,我们可以从小到大将数插入排列,类似的trick叫 Component dp 或者 插入dp。
假设现在插入到 \(A_i\) ,如何计算插入后对费用的变化呢?可以差分计算,于是记 \(dp_{i,j,k,l}\) 为填到第 \(i\) 个数,有 \(j\) 个连通分量,当前费用为 \(k\) ,以及排列的头尾被填入了几个。具体地:
- 插在两个连通块中间并将两块合并,有 \(j-1\) 种方案。
- 新增一个连通块,如果头和尾没有放就可以放,共有 \(j+1-l\) 种方案。
- 放在一个连通块的头或尾部,并且不改变 \(l\) ,有 \(2j-s\) 种方案。
- 放在整个排列的头或尾部,如果当前排列已经填入了数,则可以看作加入了这个排列中最左的连通块的左端,或最右连通块的右端。有 \(2-s\) 种方案。
对上述情况分别转移即可,最后注意到 \(i\) 这一维可以滚动数组优化。
时间复杂度:\(O(N^2L)\) 。
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
|