51nod 1134 最长递增子序列 (O(nlogn)算法)

1134 最长递增子序列

基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题

 收藏

 关注

给出长度为N的数组,找出这个数组的最长递增子序列。(递增子序列是指,子序列的元素是递增的)

例如:5 1 6 8 2 4 5 10,最长递增子序列是1 2 4 5 10。

Input

第1行:1个数N,N为序列的长度(2 <= N <= 50000)
第2 - N + 1行:每行1个数,对应序列的元素(-10^9 <= S[i] <= 10^9)

Output

输出最长递增子序列的长度。

Input示例

8
5
1
6
8
2
4
5
10

Output示例

5

常规的解法是设dp[i]表示前i位的最长上升序列长度,然后每次更新dp[i+1]都要与[0,i]进行一次比较。时间复杂度为O(n^2),完美超时。

想想怎么去优化呢?看看更新dp[i+1]需要比较这么多次吗?假设dp[i+1]=len,那么我们只要与值为len-1的去进行比较,所以不妨设b[i]表示最长上升序列为i的dp数组中的最小值。

 1 /*用数组b来存放最长上升序列,然后枚举数组a中元素看能否插入b数组。
 2 那么b数组的大小即为所求。
 3 */
 4 #include <iostream>
 5 #include <algorithm>
 6 #include <cstring>
 7 using namespace std;
 8 typedef long long ll;
 9 ll b[50005];
10 ll a[50005];
11 ll n;
12 void solve()
13 {
14     memset(b,0,sizeof(b));
15     b[0]=a[0];
16     int sum=1;
17     for(int i=1;i<n;i++)//枚举a数组
18     {
19         int pos=lower_bound(b,b+sum,a[i])-b;//lower_bound()返回值为b数组中有几个比a[i]小的
20         b[pos]=a[i];                                //或者理解为用a[i]去更新b序列应更新的位置
21         sum=max(sum,pos+1);//长度更新
22     }
23     cout<<sum<<endl;
24 }
25 int main()
26 {
27     cin>>n;
28     for(int i=0;i<n;i++)
29         cin>>a[i];
30     solve();
31     return 0;
32 }

代码才是最清晰的语言

时间: 2024-10-19 10:58:48

51nod 1134 最长递增子序列 (O(nlogn)算法)的相关文章

[2016-05-11][51nod][1134 最长递增子序列]

时间:2016-05-11 14:16:50 星期三 题目编号:[2016-05-11][51nod][1134 最长递增子序列] 题目大意:给出长度为N的数组,找出这个数组的最长递增子序列.(递增子序列是指,子序列的元素是递增的) 分析: 维护一个栈,如果是更大值,加入栈顶,否则,替换栈内第一个不小于它的数字 #include<stdio.h> #include<algorithm> #include<string.h> using namespace std; co

最长递增子序列 O(NlogN)算法

https://www.felix021.com/blog/read.php?entryid=1587&page=3&part=1 感谢作者! 标题:最长递增子序列 O(NlogN)算法 出处:Blog of Felix021 时间:Wed, 13 May 2009 04:15:10 +0000 作者:felix021 地址:https://www.felix021.com/blog/read.php?1587  内容: 今天回顾WOJ1398,发现了这个当时没有理解透彻的算法. 看了好久

51nod 1134 最长递增子序列

给出长度为N的数组,找出这个数组的最长递增子序列.(递增子序列是指,子序列的元素是递增的) 例如:5 1 6 8 2 4 5 10,最长递增子序列是1 2 4 5 10. Input 第1行:1个数N,N为序列的长度(2 <= N <= 50000) 第2 - N + 1行:每行1个数,对应序列的元素(-10^9 <= S[i] <= 10^9) Output 输出最长递增子序列的长度. Input示例 8 5 1 6 8 2 4 5 10 Output示例 5 //第一种做法,放

LCS 51Nod 1134 最长递增子序列

给出长度为N的数组,找出这个数组的最长递增子序列.(递增子序列是指,子序列的元素是递增的) 例如:5 1 6 8 2 4 5 10,最长递增子序列是1 2 4 5 10. Input 第1行:1个数N,N为序列的长度(2 <= N <= 50000) 第2 - N + 1行:每行1个数,对应序列的元素(-10^9 <= S[i] <= 10^9) Output 输出最长递增子序列的长度. Input示例 8 5 1 6 8 2 4 5 10 Output示例 5 #include

(转载)最长递增子序列 O(NlogN)算法

原博文:传送门 最长递增子序列(Longest Increasing Subsequence) 下面我们简记为 LIS. 定义d[k]:长度为k的上升子序列的最末元素,若有多个长度为k的上升子序列,则记录最小的那个最末元素.注意d中元素是单调递增的,下面要用到这个性质.首先len = 1,d[1] = a[1],然后对a[i]:若a[i]>d[len],那么len++,d[len] = a[i];否则,我们要从d[1]到d[len-1]中找到一个j,满足d[j-1]<a[i]<d[j],

51Nod 1134 最长递增子序列(动态规划O(nlogn))

1 #include <iostream> 2 #include <algorithm> 3 #include <stdio.h> 4 #define MAXN 50010 5 using namespace std; 6 7 const int MIN = -1e9; 8 9 int main(void){ 10 int n, a[MAXN], vis[MAXN], len = 1; 11 scanf("%d", &n); 12 for (

51nod 1376 最长递增子序列的数量(线段树)

51nod 1376 最长递增子序列的数量 数组A包含N个整数(可能包含相同的值).设S为A的子序列且S中的元素是递增的,则S为A的递增子序列.如果S的长度是所有递增子序列中最长的,则称S为A的最长递增子序列(LIS).A的LIS可能有很多个.例如A为:{1 3 2 0 4},1 3 4,1 2 4均为A的LIS.给出数组A,求A的LIS有多少个.由于数量很大,输出Mod 1000000007的结果即可.相同的数字在不同的位置,算作不同的,例如 {1 1 2} 答案为2. Input 第1行:1

51nod 1376: 最长递增子序列的数量(二维偏序+cdq分治)

1376 最长递增子序列的数量 Time Limit: 1 Sec Memory Limit: 128MB 分值: 160 难度:6级算法题 Description 数组A包含N个整数(可能包含相同的值).设S为A的子序列且S中的元素是递增的,则S为A的递增子序列.如果S的长度是所有递增子序列中最长的,则称S为A的最长递增子序列(LIS).A的LIS可能有很多个.例如A为:{1 3 2 0 4},1 3 4,1 2 4均为A的LIS.给出数组A,求A的LIS有多少个.由于数量很大,输出Mod 1

1134 最长递增子序列(暴力写的)

可以用二分写... 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题  收藏  关注 给出长度为N的数组,找出这个数组的最长递增子序列.(递增子序列是指,子序列的元素是递增的) 例如:5 1 6 8 2 4 5 10,最长递增子序列是1 2 4 5 10. Input 第1行:1个数N,N为序列的长度(2 <= N <= 50000) 第2 - N + 1行:每行1个数,对应序列的元素(-10^9 <= S[i] <= 10^9) Output 输出最长