Longest Ordered Subsequence
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 41944   Accepted: 18453

Description

A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequence of the given numeric sequence (a1a2, ..., aN) be any sequence (ai1ai2, ..., aiK), where 1 <= i1 < i2 < ... < iK <= N. For example, sequence (1, 7, 3, 5, 9, 4, 8) has ordered subsequences, e. g., (1, 7), (3, 4, 8) and many others. All longest ordered subsequences are of length 4, e. g., (1, 3, 5, 8).

Your program, when given the numeric sequence, must find the length of its longest ordered subsequence.

Input

The first line of input file contains the length of sequence N. The second line contains the elements of sequence - N integers in the range from 0 to 10000 each, separated by spaces. 1 <= N <= 1000

Output

Output file must contain a single integer - the length of the longest ordered subsequence of the given sequence.

Sample Input

  1. 7
  2. 1 7 3 5 9 4 8

Sample Output

  1. 4

Source

Northeastern Europe 2002, Far-Eastern Subregion
 
方法一:记忆化搜索
缺点:时间复杂度O(n^2)
  1. #include <cstdio>
  2. #include <iostream>
  3. #include <cstdlib>
  4. #include <algorithm>
  5. #include <ctime>
  6. #include <cmath>
  7. #include <string>
  8. #include <cstring>
  9. #include <stack>
  10. #include <queue>
  11. #include <list>
  12. #include <vector>
  13. #include <map>
  14. #include <set>
  15. using namespace std;
  16.  
  17. const int INF=0x3f3f3f3f;
  18. const double eps=1e-;
  19. const double PI=acos(-1.0);
  20. #define maxn 1100
  21.  
  22. int a[maxn];
  23. int dp[maxn];
  24. int dfs(int p)
  25. {
  26. if(dp[p] != -) return dp[p];
  27. int res = ;
  28. for(int i = ; i < p; i++)
  29. if(a[p] > a[i])
  30. res = max(res, dfs(i)+);
  31. dp[p] = res;
  32. return res;
  33. }
  34. int main()
  35. {
  36. int n;
  37. while(~scanf("%d", &n))
  38. {
  39. memset(dp, -, sizeof dp);
  40. for(int i = ; i < n; i++)
  41. scanf("%d", &a[i]);
  42. int pp = -;
  43. for(int j = ; j < n; j++)
  44. {
  45. pp = max(pp, dfs(j)+);
  46.  
  47. }
  48. //printf("%d\n", dfs(n-1)+ 1);
  49. printf("%d\n", pp);
  50. }
  51. return ;
  52. }

方法二:dp+二分

其中low_bound 返回第一个大于它的数的下标。

缺点:无法保存每个以 a[i]结尾的最长上升子序列。

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <cstdlib>
  4. #include <algorithm>
  5. #include <ctime>
  6. #include <cmath>
  7. #include <string>
  8. #include <cstring>
  9. #include <stack>
  10. #include <queue>
  11. #include <list>
  12. #include <vector>
  13. #include <map>
  14. #include <set>
  15. using namespace std;
  16.  
  17. const int INF=0x3f3f3f3f;
  18. const double eps=1e-;
  19. const double PI=acos(-1.0);
  20. #define maxn 11000
  21.  
  22. int a[maxn];
  23. int dp[maxn];
  24. int main()
  25. {
  26. int n;
  27. while(~scanf("%d", &n))
  28. {
  29. for(int i = ; i < n; i++)
  30. scanf("%d", &a[i]);
  31. int cnt = ;
  32. //memset(dp, INF, sizeof dp);
  33. dp[cnt] = a[];
  34. for(int i = ; i < n; i++)
  35. {
  36. if(a[i] > dp[cnt])
  37. {
  38. dp[++cnt] = a[i];
  39. }
  40. else
  41. {
  42. int pos = lower_bound(dp,dp+cnt+,a[i]) - dp;
  43. dp[pos] = a[i];
  44. }
  45. }
  46. printf("%d\n", cnt+);
  47. }
  48.  
  49. return ;
  50. }

方法三:dp+二分(优化版)

弥补了上面两种方法不足。时间复杂度为O(nlogn) 又能保存每个以a[i]结尾的最长上升子序列。

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <cstdlib>
  4. #include <algorithm>
  5. #include <ctime>
  6. #include <cmath>
  7. #include <string>
  8. #include <cstring>
  9. #include <stack>
  10. #include <queue>
  11. #include <list>
  12. #include <vector>
  13. #include <map>
  14. #include <set>
  15. using namespace std;
  16.  
  17. const int INF=0x3f3f3f3f;
  18. const double eps=1e-;
  19. const double PI=acos(-1.0);
  20. #define maxn 11000
  21.  
  22. int a[maxn];
  23. int b[maxn];
  24. int dp[maxn];
  25. int main()
  26. {
  27. int n;
  28. while(~scanf("%d", &n))
  29. {
  30. for(int i = ; i < n; i++)
  31. scanf("%d", &a[i]);
  32.  
  33. memset(dp, , sizeof dp);
  34. memset(b, INF, sizeof b);
  35. for(int i = ; i < n; i++)
  36. {
  37. int pos = lower_bound(b,b+n,a[i]) - b;
  38. dp[i] = pos+;
  39. b[pos] = a[i];
  40. }
  41. int ans = -;
  42. for(int i = ; i < n; i++)
  43. ans = max(ans, dp[i]);
  44. printf("%d\n", ans);
  45. }
  46.  
  47. return ;
  48. }

POJ-2533最长上升子序列(DP+二分)(优化版)的更多相关文章

  1. Longest Ordered Subsequence POJ - 2533 最长上升子序列dp

    题意:最长上升子序列nlogn写法 #include<iostream> #include<cstdio> #include<cstring> #include&l ...

  2. POJ 1458 最长公共子序列(dp)

    POJ 1458 最长公共子序列 题目大意:给出两个字符串,求出这样的一 个最长的公共子序列的长度:子序列 中的每个字符都能在两个原串中找到, 而且每个字符的先后顺序和原串中的 先后顺序一致. Sam ...

  3. UVa 10534 Wavio Sequence (最长递增子序列 DP 二分)

    Wavio Sequence  Wavio is a sequence of integers. It has some interesting properties. ·  Wavio is of ...

  4. POJ 2533——Longest Ordered Subsequence(DP)

    链接:http://poj.org/problem?id=2533 题解 #include<iostream> using namespace std; ]; //存放数列 ]; //b[ ...

  5. Luogu 3402 最长公共子序列(二分,最长递增子序列)

    Luogu 3402 最长公共子序列(二分,最长递增子序列) Description 经过长时间的摸索和练习,DJL终于学会了怎么求LCS.Johann感觉DJL孺子可教,就给他布置了一个课后作业: ...

  6. 【bzoj3173】【Tjoi2013】【最长上升子序列】treap+dp二分优化

    [pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=61560361 向大(hei)佬(e)实力学(di ...

  7. 【简单dp】poj 1458 最长公共子序列【O(n^2)】【模板】

    最长公共子序列可以用在下面的问题时:给你一个字符串,请问最少还需要添加多少个字符就可以让它编程一个回文串? 解法:ans=strlen(原串)-LCS(原串,反串); Sample Input abc ...

  8. POJ 1159 Palindrome-最长公共子序列问题+滚动数组(dp数组的重复利用)(结合奇偶性)

    Description A palindrome is a symmetrical string, that is, a string read identically from left to ri ...

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

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

随机推荐

  1. Java Web----Java Web的数据库操作(一)

    Java Web的数据库操作 一.JDBC技术 1.JDBC简介 JDBC是Java程序与数据库系统通信的标准API,它定义在JDK的API中,通过JDBC技术,Java程序可以非常方便地与各种数据库 ...

  2. HTML浅识

    HTML相关======= ## 认识网页 *web标准(w3c三种标准):结构标准 -->html 表现标准 -->css 行为标准 -->js **浏览器和服务器:浏览器发送报文 ...

  3. WebGIS在行业中应用的演变

    结合我本身的项目及WebGIS在公检法行业中的应用,对此作了一个演变过程的总结:         第一阶段:GIS基本功能的应用:Data Show(数据展示):Search(搜索):Search b ...

  4. Ruby中,类方法和实例方法的一个有趣的例子

    最初的代码如下: class Object def abc p "instance abc" end def self.abc p "class abc" en ...

  5. 老漏洞easy击:CVE-2012 0158占顶!

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaXF1c2hp/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/d ...

  6. Dynamics CRM 2016 使用Plug-in Trace Log调试插件

    1.写插件 首先,让我们写一个简单的插件来测试新插件跟踪日志功能.请注意,在下面的示例代码中,我们增加ITracingService的一个实例,以及记录有关插件的执行信息记录的一些键值: 2.注册插件 ...

  7. [转]iOS开发使用半透明模糊效果方法整理

    转自:http://www.molotang.com/articles/1921.html 虽然iOS很早就支持使用模糊效果对图片等进行处理,但尤其在iOS7以后,半透明模糊效果得到大范围广泛使用.包 ...

  8. <经验杂谈>C#/.Net字符串操作方法小结

    字符串操作是C#中最基本的.最常见的.也是用的最多的,以下我总结 了几种常见的方法 1.把字符串按照分隔符转换成 List /// <summary> /// 把字符串按照分隔符转换成 L ...

  9. DEV GridControl 导出到Excel

    SaveFileDialog saveFileDialog = new SaveFileDialog(); saveFileDialog.Title = "导出Excel"; sa ...

  10. JS属性读写操作+if判断注意事项

    js中不允许出现“ - ” 页面中改变文字大小-案例: <!doctype html> <html lang="en"> <head> < ...