您的位置:首页 > 其它

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

代码如下:

#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。注意:此时数组下标越界)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: