1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 最长递增子序列LIS再谈

最长递增子序列LIS再谈

时间:2020-01-06 15:30:05

相关推荐

最长递增子序列LIS再谈

DP模型:

d(i) 以第 i 个元素结尾的最长递增子序列的长度。

那么就有 d(i) = max(d(j)) + 1;(j<i&&a[j]<a[i]),答案 max(d(i)); 时间复杂度为 O(n*n);

下面介绍一个用二分优化的O(nlogn)的算法。

用一个数组g[i] 表示 d 值为 i 的数的最小的 a;即最长递增子序列为 i 时,最小的 a 是多少。

显然 g[i]<=g[2]<=g[3];

计算d[i] : 需要找到 g中大于等于a[i] 的第一个数 j ,d[i] = j;

更新g : g[j] = a[i] ;

使用STL的lower_bound可以直接求出比a[i] 大的第一个数,用的二分查找实现,总时间O(nlogn);

#include <bits/stdc++.h>using namespace std;int a[1005];int b[1005];int main(){int n;scanf("%d",&n);for(int i=0;i<n;i++)scanf("%d",&a[i]);int len = 1;b[0] = a[0];for(int i=1;i<n;i++) {if(a[i]==b[len-1])continue;if(a[i]>b[len-1])b[len++] = a[i];else {int pos = lower_bound(b,b+len,a[i])-b;b[pos] = a[i];}}printf("%d\n",len);return 0;}

View Code

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define maxn 1005#define INF 0x3f3f3f3fint a[1005];int g[1005];int binary_search(int *s,int digit,int length) {int left = 0,right = length,mid;while(right!=left) {mid = (left+right)/2;if(digit==s[mid])return mid;else if(digit<s[mid])right = mid;else left = mid+1;}return left;}int main(){int n;scanf("%d",&n);for(int i=1;i<=n;i++) {scanf("%d",&a[i]);}memset(g,INF,sizeof(INF));g[0] = -1;int len = 1;int j;for(int i=1;i<=n;i++) {j = binary_search(g,a[i],len);if(j==len)len++;g[j] = a[i];}printf("%d\n",len-1);return 0;}

View Code

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。