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

Longest Ordered Subsequence
Time Limit: 2000MS   Memory Limit: 65536K
Total 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

7
1 7 3 5 9 4 8

Sample Output

4

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


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


扫描二维码关注公众号,回复: 9390389 查看本文章

代码如下:

(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;
}




发布了79 篇原创文章 · 获赞 5 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/DNMTOOBA/article/details/76998549