造价通

反馈
取消

热门搜词

造价通

取消 发送 反馈意见

LIS序列

2018/06/19189 作者:佚名
导读: 最长上升子序列Longest Increasing Subsequence最长上升子序列:有两种基本方法:两个时间复杂度分别为O(n^2)和O(nlogn) 动态规划 对于给定数列a,元素个数为n,f[i]为以元素i结尾的最长子上升序列的最大长度。最长上升子序列f满足对任意1<=j<i<=n(a[j]<a[i]),有f[j]<f[i]。容易得出O

最长上升子序列

Longest Increasing Subsequence

最长上升子序列:

有两种基本方法:两个时间复杂度分别为O(n^2)和O(nlogn)

动态规划

对于给定数列a,元素个数为n,f[i]为以元素i结尾的最长子上升序列的最大长度。

最长上升子序列f满足对任意1<=j<i<=n(a[j]<a[i]),有f[j]<f[i]。

容易得出O(n^2)的DP状态转移方程:

f[i]=max{f[j]}+1;(1<=j<i且a[j]<a[i])

我们不妨把f的初值设为0,并在末尾添加一个元素inf,并将n++

这样经过两重循环,f[n]即为LIS长度

代码如下:

二分查找

又称作CMI算法

时间复杂度为O(nlogn)

其操作如下:

开辟一个栈b,每次取栈顶元素s和读到的元素a做比较,如果a>s,则置为栈顶;如果a<s,则二分查找栈中的比a大的第1个数,并替换。最终栈的大小即为最长递增子序列为长度

考察b栈内每个元素的含义,b[i] 表示所有长度为i的上升子序列中最小的最后一个数.

·举例:原序列为3,4,5,2,4,2

栈为3,4,5,此时读到2,则用2替换3,得到栈中元素为2,4,5,再读4,用4替换5,得到2,4,4,再读2,得到最终栈为2,2,4,最终得到的解是:

长度为1的上升子序列中最小的最后一个数是2 (2)

长度为2的上升子序列中最小的最后一个数是2 (2,2)长度为3的上升子序列中最小的最后一个数是4 (3,4,4)

可知没有长度为4的上升子序列,最长递增子序列长度为3. (3,4,4)

CMI本质是LIS问题的另一种动态规划思路

注意:CMI只能求LIS的长度和最后一个数,不能求LIS的序列!

代码如下:

#include<iostream>

using namespace std;

int n;

int a[1001],b[1001];

int rear;

int solve(int t)

{ int l=1,r=rear;

while(l<=r)

{ int mid=(l+r)>>1;

if(b[mid]>=t)//若为非递减序列,则为b[mid]>t

r=mid-1;

else

l=mid+1;

}

if(l>rear)

rear=l;

return l;

}

int main()

{ int i,j;

scanf("%d",&n);

rear=0;

for(i=1;i<=n;i++)

{

scanf("%d",&a[i]);

b[solve(a[i])]=a[i];

}

printf("%d\n",rear);

system("pause");

return 0;

}

*文章为作者独立观点,不代表造价通立场,除来源是“造价通”外。
关注微信公众号造价通(zjtcn_Largedata),获取建设行业第一手资讯

热门推荐

相关阅读