普通的思路是O(n2)的复杂度,这个题的数据量太大,超时,这时候就得用nlogn的复杂度的算法来做,这个算法的主要思想是只保存有效的序列,即最大递增子序列,然后最后得到数组的长度就是最大子序列。比如序列7 8 9 1 2 3 来说, 就是先把第一个数输入到数组中,然后继续输入后面的数,每输入一个数都要和最后一个数比较,因为这时最后一个数一定是有效序列中最大的,如果大于最后一个数,那么就直接将它放到数组的最后就行了,如果不大于最后一个数的话,就找到第一个比他大的数,然后替换它,样例中,先输入进去7, 然后再输入8,因为8 > 7, 所以直接将8放到数组的最后,同理,9也是,当输入到1的时候,判断它不比9大,这时候就需要找第一个比1大的数,这时候就用二分查找就行了,因为这个数组这样输入进去的话,肯定是有序的,找到第一个比他大的数是7,那么就替换7,现在数组中的元素分别是1, 8, 9,继续输入2,判断它不比数组的最后一个元素大,这时候继续二分找第一个比它大的,那么将替换8,同理3将会替换9,最后数组的元素分别是1, 2, 3,这是用贪心的策略来做的,因为只有保存最小的,后面的数组成最长序列的机会才会更大,所以要保存最小的.

再比如:1 8 2 4 5 先将1保存到数组中,然后再将8保存到数组中,继续判断2,不大于最后一个元素,所以找第一个比它大的,替换8,至于为什么是这样,因为同样是序列长度为2的,1 2这个序列当然要比1 8 可能的序列要长,因为后面有4,如果1 8 的话就不能长度再加一了,所以更新最小的

代码如下;

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <vector>
using namespace std;
const int N = + ;
int a[N];//保存当前最大的序列
int e;//表示当前数组中有几个元素
void replace_value(int n)//二分法查找替换
{
int left = , right = e;
int mid = (left + right) >> ;
while (left < right)
{
if (left + == right)
{
if (a[right] != n)//替换右值
a[right] = n;
return; }
if (a[mid] == n)
return;
if (a[mid] > n)
right = mid;
else
left = mid;
mid = (left + right) >> ;
}
}
int main()
{
int n;
while (~scanf("%d", &n))
{
e = ;
memset(a, , sizeof(a));
a[] = -;
int t;
for (int i = ; i < n; i++)
{ scanf("%d", &t);
if (t > a[e])//如果大于当前已有的数中最大的, 就将它添加到数组中
a[++e] = t;
else
replace_value(t);
}
cout << e << endl;
}
return ;
}

下面这个代码的思想和上面的基本相同,我是看的网上的,大体思路就是先将数据输入到一个数组中,然后在一个一个的判断,找每个元素应该在的位置,也就是上面的那种思想,不过不如上面的那个简单

#include <stdio.h>

const int N =  + ;
int a[N], b[N];//a来存放输入的元素,b来存放当前最长子序列元素
//寻找n所在b当中的位置,二分查找,时间复杂度logn;
int search_pos(int n, int len)
{
int left = , right = len;
int mid = (left + right) >> ;
while (left <= right)
{
if (b[mid] == n)
return mid;
else if (b[mid] < n)
left = mid + ;
else
right = mid - ;
mid = (left + right) >> ;
}
return left;
}
int main()
{
int n;
while (~scanf("%d", &n))
{
for (int i = ; i < n; i++)
scanf("%d", &a[i]);
b[] = a[];
int len = ;
int j;
for (int i = ; i < n; i++)
{
j = search_pos(a[i], len);//找到第一个比他大的位置,如果已经是最大,那么就是b数组的最后一个位置
b[j] = a[i];
if (j > len)//如果是最后一个位置,len更新为j
len = j;
}
printf("%d\n", len);
}
return ;
}

NYOJ 214 最长上升子序列nlogn的更多相关文章

  1. HDU 1025 Constructing Roads In JGShining's Kingdom(求最长上升子序列nlogn算法)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1025 解题报告:先把输入按照r从小到大的顺序排个序,然后就转化成了求p的最长上升子序列问题了,当然按p ...

  2. 【算法】最长公共子序列(nlogn)

    转载注明出处:http://blog.csdn.net/wdq347/article/details/9001005 (修正了一些错误,并自己重写了代码) 最长公共子序列(LCS)最常见的算法是时间复 ...

  3. [poj 1533]最长上升子序列nlogn树状数组

    题目链接:http://poj.org/problem?id=2533 其实这个题的数据范围n^2都可以过,只是为了练习一下nlogn的写法. 最长上升子序列的nlogn写法有两种,一种是变形的dp, ...

  4. HDU5748---(记录每个元素的 最长上升子序列 nlogn)

    分析: 给一个序列,求出每个位置结尾的最长上升子序列 O(n^2) 超时 #include "cstdio" #include "algorithm" #def ...

  5. 最长公共子序列 nlogn

    先来个板子 #include<bits/stdc++.h> using namespace std; , M = 1e6+, mod = 1e9+, inf = 1e9+; typedef ...

  6. nyoj 36 最长公共子序列【LCS模板】

    最长公共子序列 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 咱们就不拐弯抹角了,如题,需要你做的就是写一个程序,得出最长公共子序列.tip:最长公共子序列也称作最 ...

  7. nyoj 36 最长公共子序列

    描述 咱们就不拐弯抹角了,如题,需要你做的就是写一个程序,得出最长公共子序列. tip:最长公共子序列也称作最长公共子串(不要求连续),英文缩写为LCS(Longest Common Subseque ...

  8. DP练习 最长上升子序列nlogn解法

    openjudge 百练 2757:最长上升子序列 总时间限制:  2000ms 内存限制:  65536kB 描述 一个数的序列bi,当b1 < b2 < ... < bS的时候, ...

  9. NYOJ 36 最长公共子序列 (还是dp)

    这个好多算法书上都有,不仅限于<算法导论> 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描写叙述 咱们就不拐弯抹角了,如题.须要你做的就是写一个程序,得出最长公 ...

随机推荐

  1. FingerChaser(3) 解题报告目录

    所有代码都不超过40行... A:http://www.cppblog.com/willing/archive/2010/05/04/114304.html B:http://www.cnblogs. ...

  2. FindBugs的Eclipse插件安装与使用

    1.FindBugs介绍 FindBugs是一款Java静态代码分析工具,与其他静态分析工具(如Checkstyle和PMD)不同,FindBugs 不注重样式或者格式,它专注于寻找真正的缺陷或者潜在 ...

  3. 写了一个jquery的 弹出层插件。

    下载地址:http://pan.baidu.com/s/1eQ26CMm ps:ajax加载做的,要有环境才能正常运行哦! //这是一个以ajax加载显示弹出层插件  参数(option): widt ...

  4. php拦截器(魔术方法)

    什么是PHP拦截器? 英文名称 “interceptor”,作用是 拦截 发送未定义的方法和属性的消息. 先看一段代码,定义了一个School类,实例化一个对象$obj,获取一个未定义的属性teach ...

  5. HTML&CSS基础学习笔记1.32-选择器是什么

    选择器是什么 选择器是CSS样式为了定位页面上的任意元素的一种方法. 选择器主要分为:元素标签选择器.通用选择器.类选择器.ID选择器.属性选择器.组合选择器.伪类选择器.伪元素选择器. 先做个了解, ...

  6. 随机数是骗人的,.Net、Java、C为我作证(转载)

      几乎所有编程语言中都提供了"生成一个随机数"的方法,也就是调用这个方法会生成一个数,我们事先也不知道它生成什么数.比如在.Net中编写下面的代码: Random rand = ...

  7. mongod的主要参数有

    ------------------------------------基本配置----------------------   --quiet # 安静输出 --port arg # 指定服务端口号 ...

  8. Excel--java POi

    import java.io.File; import java.io.FileOutputStream; import org.apache.commons.io.FileUtils; import ...

  9. 一起学习iOS开发专用词汇,每天记3个,助你变大牛-b

    大家做开发最大的问题是什么?英语的问题应该困扰很多的同学的地方,我们提倡科学学习开发中的常用词汇.我们不要求大家有特别好的听.说.写,只要能够记住,能够认识这些常用词汇你以后的开发也将游刃有余.我们的 ...

  10. WordPress网站更换老鹰主机详细操作

    眼看着之前买的虚拟主机就要到期了,本着节约至上的美德,就和同事一起买了老鹰主机.因为第一次网站的配置是一个朋友帮忙的,所以现在想完全自己动手操作,毕竟之后的博客维护还是得靠自己.下面就来和我一起学习怎 ...