bailian--oj--2757(最長上升子序列)

bailian--oj--2757(最長上升子序列)

最長上升子序列
Crawling in process... Crawling failed Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

Description

一個數的序列 bi,當 b1 < b2 < ... < bS的時候,我們稱這個序列是上升的。對於給定的一個序列( a1, a2, ..., aN),我們可以得到一些上升的子序列( ai1, ai2, ..., aiK),這裏1 <= i1 < i2 < ... < iK <= N。比如,對於序列(1, 7, 3, 5, 9, 4, 8),有它的一些上升子序列,如(1, 7), (3, 4, 8)等等。這些子序列中最長的長度是4,比如子序列(1, 3, 5, 8).

你的任務,就是對於給定的序列,求出最長上升子序列的長度。

Input

輸入的第一行是序列的長度N (1 <= N <= 1000)。第二行給出序列中的N個整數,這些整數的取值範圍都在0到10000。

Output

最長上升子序列的長度。

Sample Input

7
1 7 3 5 9 4 8

Sample Output

4
My  solution:

/*2016.4.13*/

/*o(n*n)算法AC*/

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[1100],dp[1100];
int main()
{
	int i,j,k,temp,n;
	while(scanf("%d",&n)==1)
	{
		for(i=1;i<=n;i++)
		scanf("%d",&a[i]);
		dp[1]=1;
		for(i=2;i<=n;i++)
		{
			temp=0;
			for(j=1;j<i;j++)
			{
				if(a[i]>a[j])
				{
					if(temp<dp[j])
					temp=dp[j];
				}
			}
			dp[i]=temp+1;
		}
		sort(dp+1,dp+n+1);//注意;之前一直出錯,最後才發現錯在這裏,sort(dp+1,dp+n); 
		printf("%d\n",dp[n]);
	}

	return 0;
 } 


/*nlogn算法AC*/

#include<stdio.h>
#include<cstring>
#include<algorithm>
using namespace std;
int a[11000],dp[10010],n,k,dp1[10010];
int search(int t)//二分查找 
{
	int left,right,temp;
	left=1;right=k;
	while(left<=right)
	{
		temp=(left+right)/2;
		if(dp[temp]<t&&dp[temp+1]>=t)
		return temp+1;
		if(dp[temp]==t)
		return temp;
		
		if(dp[temp]>t)
			right=temp;
		else
			left=temp+1;
	}
}
int main()
{
	int i,j,temp;
	while(scanf("%d",&n)==1)
	{
		memset(dp,0x3f,sizeof(dp)); 
		for(i=1;i<=n;i++)
		scanf("%d",&a[i]);
		dp[1]=a[1];
		k=1;
		for(i=2;i<=n;i++)
		{
			if(a[i]>dp[k])
			{
				j=k+1;
				k++;
			}
			else
			{
					if(a[i]<=dp[1])//之前一直出錯,最後才發現錯寫成 a[i]<=a[1]了,心裏苦啊! 
					j=1;
					else
					j=search(a[i]);
		    }
			dp[j]=a[i];
		}
		printf("%d\n",k);
	}
	return 0;
}






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