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

7
1 7 3 5 9 4 8

Sample Output

4

Source

Northeastern Europe 2002, Far-Eastern Subregion
 
方法一:记忆化搜索
缺点:时间复杂度O(n^2)
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <ctime>
#include <cmath>
#include <string>
#include <cstring>
#include <stack>
#include <queue>
#include <list>
#include <vector>
#include <map>
#include <set>
using namespace std; const int INF=0x3f3f3f3f;
const double eps=1e-;
const double PI=acos(-1.0);
#define maxn 1100 int a[maxn];
int dp[maxn];
int dfs(int p)
{
if(dp[p] != -) return dp[p];
int res = ;
for(int i = ; i < p; i++)
if(a[p] > a[i])
res = max(res, dfs(i)+);
dp[p] = res;
return res;
}
int main()
{
int n;
while(~scanf("%d", &n))
{
memset(dp, -, sizeof dp);
for(int i = ; i < n; i++)
scanf("%d", &a[i]);
int pp = -;
for(int j = ; j < n; j++)
{
pp = max(pp, dfs(j)+); }
//printf("%d\n", dfs(n-1)+ 1);
printf("%d\n", pp);
}
return ;
}

方法二:dp+二分

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

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

#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <ctime>
#include <cmath>
#include <string>
#include <cstring>
#include <stack>
#include <queue>
#include <list>
#include <vector>
#include <map>
#include <set>
using namespace std; const int INF=0x3f3f3f3f;
const double eps=1e-;
const double PI=acos(-1.0);
#define maxn 11000 int a[maxn];
int dp[maxn];
int main()
{
int n;
while(~scanf("%d", &n))
{
for(int i = ; i < n; i++)
scanf("%d", &a[i]);
int cnt = ;
//memset(dp, INF, sizeof dp);
dp[cnt] = a[];
for(int i = ; i < n; i++)
{
if(a[i] > dp[cnt])
{
dp[++cnt] = a[i];
}
else
{
int pos = lower_bound(dp,dp+cnt+,a[i]) - dp;
dp[pos] = a[i];
}
}
printf("%d\n", cnt+);
} return ;
}

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

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

#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <ctime>
#include <cmath>
#include <string>
#include <cstring>
#include <stack>
#include <queue>
#include <list>
#include <vector>
#include <map>
#include <set>
using namespace std; const int INF=0x3f3f3f3f;
const double eps=1e-;
const double PI=acos(-1.0);
#define maxn 11000 int a[maxn];
int b[maxn];
int dp[maxn];
int main()
{
int n;
while(~scanf("%d", &n))
{
for(int i = ; i < n; i++)
scanf("%d", &a[i]); memset(dp, , sizeof dp);
memset(b, INF, sizeof b);
for(int i = ; i < n; i++)
{
int pos = lower_bound(b,b+n,a[i]) - b;
dp[i] = pos+;
b[pos] = a[i];
}
int ans = -;
for(int i = ; i < n; i++)
ans = max(ans, dp[i]);
printf("%d\n", ans);
} return ;
}

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. 旋的X-Di

    旋的X-Di | 氪加 旋的X-Di

  2. URAL 1036

    题目大意:求前N位与后N位各个位和相等且总和等于S的2N位数的个数. KB     64bit IO Format:%I64d & %I64u 数据规模:1<=N<=50,0< ...

  3. 关于<ul><ol><li>的用法

    <ul>:无序列表 <ol>:有序列表 <li>:行. 想要去掉前面的序号和点可以在<ol>或<ul>style中用list-style: ...

  4. JAVA中运用数组的四种排序方法

    JAVA中在运用数组进行排序功能时,一般有四种方法:快速排序法.冒泡法.选择排序法.插入排序法. 快速排序法主要是运用了Arrays中的一个方法Arrays.sort()实现. 冒泡法是运用遍历数组进 ...

  5. stardict词典(星际译王)

    sudo apt-get install stardict 下载词库: http://abloz.com/huzheng/stardict-dic/zh_CN/ 把下载的压缩包解压,以a为例cd /u ...

  6. 小米路由器mini搭建个人静态网站的方法

    小米路由和小米路由mini从本质上来说差距就在1T的硬盘上,其它并没有明显差别,但是功能却差很多,例如:小米路由有自带的LAMP模式,而小米路由mini则没有,换句话说,其实这个功能是被阉割了,仔细研 ...

  7. C/C++基础概念

    1.类占用的内存大小: 1)在不同位数的操作系统下,各种数据类型所占用的内存大小:32位和64位操作系统 http://blog.csdn.net/b_zhang/article/details/68 ...

  8. tomcat线程数查看

    获取tomcat进程pid ps -ef|grep tomcat 统计该tomcat进程内的线程个数 ps -Lf 29295 |wc -l

  9. [转]CSS目标伪类E:target

    CSS3 target 伪类不得不说那些事儿(纯CSS实现tab切换) 是不是觉得target有点眼熟?! 今天要讲的不是HTML的<a>标签里面有个target属性. target伪类是 ...

  10. Windows命令行(DOS命令)教程–2 (转载) http://arch.pconline.com.cn//pcedu/rookie/basic/10111/15325_1.html

    二.符号约定 为了便于说明格式,这里我们使用了一些符号约定,它们是通用的: C: 盘符 Path 路径 Filename 文件名 .ext 扩展名 Filespec 文件标识符 [ ] 方括号中的项目 ...