首先说说ACwing895,典中典问题,本文主要是详讲下其中细节
状态表示很显然就是f[i] ->表示前i个数中最长的上升序列长度,注意其中有一点要注意这里f[i]还包含一个意义就是选择了第i个数
所以我们能够得到一个状态转移方程,逐个比较前i-1个数,取f[i] = max(f[i], f[k] - 1) k 为 a[k] < a[i]且k < i。
还有一点值得注意,我们的f[i]的最小值为1,因为至少有他一个。
虽然这个想法很DP,但他的复杂度很不美妙,他的总循环测试为(1+2+。。。+N-1)N为数据量,显然这是一个n2复杂度的东西,10^5以上的数据就会被卡。
一个新的状态定义带来的状态转移改变了一切。
f[i]表示长度为i的上升子序列的最小尾数。
我们对0到size-1每个元素进行操作
我们在长为length的f数组进行查找,并且想要寻找到小于a[i]的最大尾数,二分可以实现,那么我们查找到的长度再+1的最小尾数就会被更新为当前值(分类讨论可证明,如果长度+1的序列尾数比当前值大,那么肯定能进行更新,如果相等,那么更新也无事发生,如果小于,那么它应该是会被二分到,这里没有二分到这个值说明这个值不会比当前值大),如果找不到最大尾数,那么说明当前数是最大的,他能更新f数组长度,新长度为length + 1