普通的思路是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 = 100000 + 10;
int a[N];//保存当前最大的序列
int e;//表示当前数组中有几个元素
void replace_value(int n)//二分法查找替换
{int left = 0, right = e;int mid = (left + right) >> 1;while (left < right){if (left + 1 == right){if (a[right] != n)//替换右值a[right] = n;return;}if (a[mid] == n)return;if (a[mid] > n)right = mid;elseleft = mid;mid = (left + right) >> 1;}
}
int main()
{int n;while (~scanf("%d", &n)){e = 0;memset(a, 0, sizeof(a));a[0] = -2147483648;int t;for (int i = 0; i < n; i++){scanf("%d", &t);if (t > a[e])//如果大于当前已有的数中最大的, 就将它添加到数组中a[++e] = t;elsereplace_value(t);}cout << e << endl;}return 0;
}

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

#include <stdio.h>const int N = 100000 + 10;
int a[N], b[N];//a来存放输入的元素,b来存放当前最长子序列元素
//寻找n所在b当中的位置,二分查找,时间复杂度logn;
int search_pos(int n, int len)
{int left = 1, right = len;int mid = (left + right) >> 1;while (left <= right){if (b[mid] == n)return mid;else if (b[mid] < n)left = mid + 1;else right = mid - 1;mid = (left + right) >> 1;}return left;
}
int main()
{int n;while (~scanf("%d", &n)){for (int i = 0; i < n; i++)scanf("%d", &a[i]);b[1] = a[0];int len = 1;int j;for (int i = 1; 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 0;
}

转载于:https://www.cnblogs.com/Howe-Young/p/4104152.html

NYOJ 214 最长上升子序列nlogn相关推荐

  1. 最长连续子序列nlogn算法

    最长上升子序列(LIS)长度的O(nlogn)算法 标签: 算法search优化存储 2012-04-18 19:38 14031人阅读 评论(5) 收藏 举报  分类: 资料学习(15)  解题报告 ...

  2. 最长上升子序列nlogn算法

    原博主:dangwenliang 网址http://blog.csdn.net/dangwenliang/article/details/5728363 ----------------------- ...

  3. c语言最长递增子序列nlogn,最长递增子序列

    问题定义: 给定一个长度为N的数组,找出一个最长的单调自增子序列(不一定连续,但是顺序不能乱).例如:给定一个长度为6的数组A{5, 6, 7, 1, 2, 8},则其最长的单调递增子序列为{5,6, ...

  4. c语言最长递增子序列nlogn,十月常见算法考题、最长递增子序列,Leetcode第300题最长上升子...

    十月常见算法考题.最长递增子序列,Leetcode第300题最长上升子 十月常见算法考题.最长递增子序列,Leetcode第300题最长上升子序列的变种,我没见过乔丹,今天詹姆斯就是我的神! @Aut ...

  5. NYOJ 36 最长公共子序列

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

  6. NYOJ 36 最长公共子序列 dp

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

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

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

  8. 最长公共子序列nlogn求法

    首先我们可以看到,普通的 O ( n 2 ) O(n^2) O(n2)的求法是不现实的,因为最大的数据量是 1 e 5 1e5 1e5 我们考虑这么一个变化,以样例为例子 3 − 2 − 1 − 4 ...

  9. 求最长上升子序列——LIS的O(nlogn)算法(二分)

    LIS的O(nlogn)算法(二分) 传送门:点我 O(n^2)解法:(n为4w,TLE) memset(dp,1,sizeof(dp)); int ans=-1; for(i=2; i<=n; ...

最新文章

  1. 格式化json日期'/Date(-62135596800000)/'
  2. 《JavaScript应用程序设计》一一3.2 流式JavaScript
  3. tomcat主目录(ROOT.xml)和虚拟目录
  4. React入门---事件与数据的双向绑定-9
  5. 《算法基础》——2.3 求幂运算
  6. 统计学习及监督学习概论
  7. spring boot+mybatisplus集成后访问项目接口404
  8. 计算机专业毕业求职,计算机专业毕业生求职简历
  9. 【Kibana】FATAL Error: [config validation of [elasticsearch].url]: definition for this key is missing
  10. Excel 中 添加 复选框。
  11. php接口和多态的概念以及简单应用
  12. atitit 研发管理 要不要自己做引擎自己实现架构?.docx
  13. java编程思想.pdf,阿里开发手册.pdf,MySQL是怎样运行的_掘金小册_.pdf
  14. FishC笔记—21 讲 函数:lambda表达式
  15. matlab中whos怎么用,【安富莱DSP教程】第3章 Matlab 简易使用(一)
  16. Hadoop | 初学基础原理
  17. 什么是Photoshop中的图层和蒙版?
  18. canvas中手动绘制椭圆的方法
  19. 光纤猫怎样连接无线路由器?_网络技术-i火吧
  20. 1、u3d 下载、安装

热门文章

  1. 深度学习的实用层面 —— 1.14 关于梯度检验实现的标记
  2. leetcode - 764. 最大加号标志
  3. LeetCode自我总结(对链表进行插入排序)
  4. STM32 - 定时器高级应用说明 - 01 - Filtering stage - 波形输入的过滤
  5. 串口 多个activity 安卓_一个Activity实时向另一个Activity发送消息
  6. 各纬度气候分布图_印度和中国都是季风气候显著的国家,但冬夏季风的强弱却完全不同...
  7. python中for循环-python中关于for循环的碎碎念
  8. 【script】python3使用http.server搭建简易web服务
  9. 前端证券项目_证监会公告[2018]6号 证券公司投资银行类业务内部控制指引
  10. 计算机原理语言方框图,计算机原理整理原版1.10.docx