zoj1986,poj1631,最长上升子序列,复杂度O(n*logn)
2013-08-19 15:51
330 查看
链接:http://poj.org/problem?id=1631
题意:最长上升子序列。复杂度为O(n*logn).
思路:这道题只能用nlogn的算法,n^2的话会卡掉。
下面这两个个链接介绍nlogn的算法讲的还可以。
http://www.cnblogs.com/celia01/archive/2012/07/27/2611043.html
http://blog.sina.com.cn/s/blog_4b1e4fe9010098af.html
代码如下:
View Code
上面使用的STL中的fill()函数和lower_bound()函数。
简略简绍下。
fill()函数它的原理是把那一块单元赋成指定的值,与memset不同,
memset则是按字节填充的。
例如:
使用fill()函数,数组d[]中的元素都赋值为数字1,使用memset()函数,数组d[]中的元素都赋值为数字(1<<24)+(1<<16)+(1<<8)+1 = 16843009.
iterator lower_bound( const key_type &key ): 返回一个迭代器,指向键值>= key的第一个元素。
iterator upper_bound( const key_type &key ):返回一个迭代器,指向键值> key的第一个元素。
lower_bound()在 [first , last) 这个前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置。(注意:此时数组下标越界)
upper_bound()也是在 [first , last) 这个前闭后开区间进行二分查找,如果插入元素大于数组中全部元素,返回的是last。(注意:此时数组下标越界)
题意:最长上升子序列。复杂度为O(n*logn).
思路:这道题只能用nlogn的算法,n^2的话会卡掉。
下面这两个个链接介绍nlogn的算法讲的还可以。
http://www.cnblogs.com/celia01/archive/2012/07/27/2611043.html
http://blog.sina.com.cn/s/blog_4b1e4fe9010098af.html
代码如下:
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> #include<vector> using namespace std; const int maxn=40005; const int INF=1000000; int n,a[maxn],d[maxn]; int main() { // freopen("ine.cpp","r",stdin); int t; scanf("%d",&t); while(t--) { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); fill(d,d+n,INF); for(int i=1;i<=n;i++) *lower_bound(d,d+n,a[i])=a[i]; printf("%d\n",lower_bound(d,d+n,INF)-d); } return 0; }
View Code
上面使用的STL中的fill()函数和lower_bound()函数。
简略简绍下。
fill()函数它的原理是把那一块单元赋成指定的值,与memset不同,
memset则是按字节填充的。
例如:
int main() { int d[100]; fill(d,d+100,1); for(int i=0; i<100; i++) cout<<d[i]<<" "; cout<<endl; memset(d,1,100*sizeof(int)); for(int i=0; i<100; i++) cout<<d[i]<<" "; cout<<endl; }
使用fill()函数,数组d[]中的元素都赋值为数字1,使用memset()函数,数组d[]中的元素都赋值为数字(1<<24)+(1<<16)+(1<<8)+1 = 16843009.
iterator lower_bound( const key_type &key ): 返回一个迭代器,指向键值>= key的第一个元素。
iterator upper_bound( const key_type &key ):返回一个迭代器,指向键值> key的第一个元素。
lower_bound()在 [first , last) 这个前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置。(注意:此时数组下标越界)
upper_bound()也是在 [first , last) 这个前闭后开区间进行二分查找,如果插入元素大于数组中全部元素,返回的是last。(注意:此时数组下标越界)
相关文章推荐
- UVALive2931 POJ1631 HDU1950 ZOJ1986 Bridging signals【最长上升子序列+二分+堆栈】
- zoj 1986 || poj 1631 Bridging Signals(最长上升子序列N*logN)
- zoj 2319 Beautiful People 【最长上升序列】
- ZOJ 1986 最长上升子序列
- 最长上升子序列(LIS) 两种复杂度算法
- 最长上升子序列(logN算法)
- zoj 1986(最长上升子序列)
- 最长上升子序列(HDU 1423,PKU 1887,ZJU1986)(c++) 可输出序列
- poj1631(最长上升子序列 nlogn)
- ZOJ3627 POJ1631 HDU1950 Bridging Signals,O(N*logN)版最长上升子序列问题
- 最长上升子序列 nlogn时间复杂度 poj 2533
- zoj 2136 Longest Ordered Subsequence 最长上升子序列 新思路
- POJ 1631 Bridging signals(最长上升子序列 n*logn && POJ 3903)
- n*logn最长上升序列
- n*logn最长上升序列
- (LCIS)最长公共上升子序列 ZOJ 2432
- zoj 2136 Longest Ordered Subsequence(最长上升子序列,第二次写 = =)
- zju 1986 Bridging Signals(最长上升非降子序列)
- ZOJ 2319 最长上升子序列并输出组成该序列的元素编号
- zoj 2136 Longest Ordered Subsequence 最长上升子序列 新思路