最长不下降子序列nlogn做法及其拓展

最长不下降子序列nlogn做法及其扩展

前言&nlogn做法

LIS表示最长不下降子序列

考虑设\(f_i\)表示LIS长度为i的最小值(具有单调性),对于每个新的x,二分出最大的满足\(f_i\)小于等于x的位置w,更新w+1

还有一种单调栈理解法,假若已经维护了一个LIS在单调栈里,对于一个新的x,二分出最大的满足值小于等于x的位置w,更新w+1,可以证明不会影响答案(其实代码来说是一样的)

[P7931 [COCI2021-2022#1] Volontiranje

给定一个 \(1\sim n\) 的排列 \(p\),请从这里面取出尽可能多的不交的上升子序列,且他们的长度为原排列的 LIS 的长度,并构造一组方案。

考虑用二分找到LIS长度len,然后把把出现在\(f_i\)中的数字都压进一个栈里(先出现的在栈顶)

于是我们得到len个栈:

其中每个栈中的元素单调递减,且总数为n

然后考虑构造一个LIS就只能从每个栈中各选一个,可以想到先取栈顶,若合法就取下一个栈,否则就pop,直到全部的栈为空

可以发现一定能取出最多的LIS

石中剑的考验

给出1 ∼ n的一个排列的一个最长上升子序列(长度为k,\(n\le15\)),求原排列可能的种类数。

其中原排列合法的充要条件是:

  1. 给出的子序列是原排列的子序列;

  2. 原排列的最长上升子序列长度为k。

发现n比较小,考虑状压,根据我们nlogn的单调栈思想,设\(f_{s}\),s是三进制,0/1/2表示未选/选了不在栈中/选了在栈中

然后n转移,跑不满

posted @ 2024-02-23 22:19  zhy_learn  阅读(16)  评论(0编辑  收藏  举报