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 );


代碼如下:

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




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章