50 likes | 212 Views
LIS 最长上升子序列. 求数列{ a1,a2,a3…an }的最长上升子序列 朴素方法 F[i]: 以 i 为最高结束的最长上升子序列 F[i]:=max{f[j]+1} (aj<ai 且 j<i) 时间复杂度 O(n 2 ). i. j. 让 a[i] 在左边找一个第 2 高 ( 枚举 ) ,站在它右边. LIS 最长上升子序列. i. 让 a[i] 在左边找一个第 2 高 ( 枚举 ) ,站在它右边. j. F[i]:=max{f[j]+1} (aj<ai 且 j<i)
E N D
LIS最长上升子序列 • 求数列{a1,a2,a3…an}的最长上升子序列 • 朴素方法 • F[i]:以i为最高结束的最长上升子序列 • F[i]:=max{f[j]+1} (aj<ai且j<i) • 时间复杂度O(n2) i j 让a[i]在左边找一个第2高(枚举),站在它右边
LIS最长上升子序列 i 让a[i]在左边找一个第2高(枚举),站在它右边 j • F[i]:=max{f[j]+1} (aj<ai且j<i) • 在枚举j的过程中,如果有多个f[j]都是最大的,怎么办?有没有可以利用的信息? • 不难发现,对F值相同的多个j来说,j越矮越好。J越矮,后边机会越多。 • 如何利用上边这个信息? • 设g[i]:最优值F取i时的最小的a[i](最矮)
让a[i]在左边找一个最长的第2高(枚举),站在它右边让a[i]在左边找一个最长的第2高(枚举),站在它右边 i 而这个第2高越矮越好 j LIS最长上升子序列 • 设g[i]:最优值F取i时的最小的a[i](最矮) • 寻找f值与g值的关系可以发现: • F[i]=左边第一个g值<a[i]的F值+1 • 即,f[i]=他左边最长的(第二高)F值+1 优化关键
让a[i]在左边找一个最长的第2高(枚举),站在它右边让a[i]在左边找一个最长的第2高(枚举),站在它右边 i 而这个第2高越矮越好 保存在g[长度]中 j LIS最长上升子序列 • 不难看出,g值是单调递增的。 • 二分查找可将算法优化至nlogn 优化关键
二分查找框架 • Find(x,a,b),在区间[a,b]中找x • Begin • while b-a>1 do • begin • m:=(a+b)div 2 • if x>=m then a:=m • if x<=m then b:=m • end; • End; a m b