Longest Ordered Subsequence 【poj-2533】【动态规划-最长上升子序列】

来源:互联网 发布:mac开发网站 编辑:程序博客网 时间:2024/06/05 14:36

Longest Ordered Subsequence
Time Limit: 2000MS Memory Limit: 65536KTotal Submissions: 54233 Accepted: 24254

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

71 7 3 5 9 4 8

Sample Output

4

题意:求最长上升子序列的长度;


题解:两种算法:O( n ^ 2 ) 和 O( n * log n );


代码如下:

(1) O( n ^ 2 ) 

定义dp[ i ]:  以a[ i ]为结尾的最长上升子序列的长度。

那么以a[ i ]为结尾的上升子序列是以下其中之一

 ①只包含a[ i ]的子序列  (a[ i ]比前面的任何数都小,所以重新立一个序列) 

 ②在满足 j < i 并且a[ j ] < a[ i ] 的以a[ j ] 为结尾的上升子序列末尾,再加上a[ i ]后得到的子序列  

递推关系为:  dp[ i ] = max { 1 , dp[ j ] + 1( 当 j < i 且a[ j ] < a[ i ] 时)}



#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int maxn=1005;int a[maxn];int dp[maxn];int main(){int n;while(~scanf("%d",&n)){for(int i=0;i<n;i++)scanf("%d",&a[i]);int ans=0;for(int i=0;i<n;i++){dp[i]=1;for(int j=0;j<i;j++){if(a[j]<a[i])dp[i]=max(dp[i],dp[j]+1);}ans=max(ans,dp[i]);}printf("%d\n",ans);}return 0;}


(2) O( n * log n )

定义 dp[ i ]: 长度为 i + 1 的上升子序列中末尾元素的最小值 

首先将 dp 数组初始化为 INF ,然后对 a数列中的元素逐个遍历;对于每个a[ i ] 的值,遍历所有 dp 直到找到一个dp[ j ]的值大于等于 a[ i ]然后用a[ i ]赋值给 dp[ j ];

最后记录 dp数组中 不为 INF的值的数量即可。


#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int maxn=1005;const int INF=0x3f3f3f3f;int a[maxn];int dp[maxn];int main(){int n;while(~scanf("%d",&n)){for(int i=0;i<n;i++)scanf("%d",&a[i]);for(int i=0;i<n;i++)dp[i]=INF;int num=0;for(int i=0;i<n;i++){int pos=lower_bound(dp,dp+n,a[i])-dp;dp[pos]=a[i];}for(int i=0;i<n;i++){if(dp[i]!=INF) num++;else break;}printf("%d\n",num);}return 0;}




阅读全文
0 0
原创粉丝点击