【典】一个计数小技巧

其实是一个比较常用的数数技巧,但是遇到题目的时候总是忘掉。

就是形如已知一个序列,求有多少个排列满足一个条件,这个条件一般是制约相邻两个元素的。

那么可以采用一个技巧就是序列排序,然后按照某种顺序插入。


ABC267G *2561 \(\color{blue}\bigstar\)

有一个长度为 \(n\) 的序列 \(a\),求有多少种排列方式满足恰好 \(k\)\(1\le i<n\),满足 \(a_i<a_{i+1}\)
\(n\le 5000\)

考虑有多少排列问题,那么可以先对 \(a\) 排序然后依次插入。

每次插入一个最大值,那么只需要求有多少个位置满足插入后满足条件的位置 \(+1\),然后直接跑一遍简单的背包即可。

code


ARC148E *2785 \(\color{Gold}\bigstar\)

有一个长度为 \(n\) 的序列,求有多少个不同的排列满足所有 \(1\le i<n\) 满足 \(a_i+a_{i+1}\ge k\)

\(n\le 2\times 10^5\)

考虑先排序,如果从小到大,会发现很难搞,因为满足条件位置数量一直在变化。

考虑从小到大加入一个数前,先把与他满足条件的点都加入,那么可以发现可以插入的位置数就是固定的了。

具体而言,维护区间 \([l,r]\),不断向中间移动,那么可以发现如果 \(l,r\) 满足就把 \(r\) 放入,否则放入 \(l\),考虑这样对于 \([r+1,n]\),这些数的旁边都可以放,而对于 \([1,l-1]\) 就都不行,因此可以直接算了。

code

posted @ 2022-09-12 21:23  houzhiyuan  阅读(259)  评论(0编辑  收藏  举报