LIS(最长上升子序列)

 这是O(n^2)的算法:

#include<stdio.h>
int main()
{
    int n,i,k,max,lis[1001],num[1001];
    while(scanf("%d",&n)!=EOF)
    { 
        for(i=0;i<n;i++)
        {
            scanf("%d",&num[i]);
            lis[i]=1;
        }
        for(i=1;i<n;i++)
            for(k=0;k<i;k++)
                if(num[k]<=num[i]&&lis[i]<lis[k]+1) //当前数比之前数大&&当前记录值≤之前记录值,这样,把当前记录值加一
                    lis[i]++;
        max=1;
        for(i=0;i<n;i++)
            if(max<lis[i])
                max=lis[i];
        printf("%d\n",max);
    }
    return 0;
}

O(n*log2n)的算法:用到二分

例如:

lis[]中原先存入:1 5 7,再输入新数据num=3,则更新lis[1]=5为lis[1]=3,即求比num大的最小的lis[]中的数,进行替换。

//求最长上升子序列 
#include<stdio.h>
int lis[40001]; 
int binarysearch(int left,int right,int number) 
{ 
	int mid; 
	while(left<=right) 
	{ 
		mid=left+(right-left)/2; 
		if(lis[mid]<number) left=mid+1; 
		else right=mid-1; 
	} 
	return right; 
} 
int main() 
{ 
	//freopen("input.txt","r",stdin); 
	//freopen("output.txt","w",stdout); 
	int n,p,i,tot,num,meet; 
	while(scanf("%d",&n)!=EOF) 
	{ 
		while(n--) 
		{ 
			scanf("%d%d",&p,&num); 
			lis[0]=num; 
			tot=1; 
			for(i=1;i<p;i++) 
			{ 
				scanf("%d",&num); 
				if(num>lis[tot-1]) 
					lis[tot++]=num; //如果num比lis[]末尾数大,则lis[]下标自增,存入num 
				else if(num<lis[tot-1]) //如果num比lis[]末尾数小,则用二分法找到比num大的最小的数的下标,然后进行替换 
				{ 
					meet=binarysearch(0,tot-1,num); 
					lis[meet+1]=num; 
				} 
			} 
			printf("%d\n",tot); 
		} 
	} 
	return 0; 
}

我还看到另一种用二分做的,还没想明白,继续研究

//最长不下降子序列
#include<stdio.h>
int lis[1002]; 
int binarysearch(int left, int right, int number) 
{ 
	int mid; 
	while(left<=right) 
	{ 
		mid=left+(right-left)/2; 
		if(lis[mid]<=number) left=mid+1; //
		else right=mid-1; 
	} 
	return left; 
} 
int main() 
{ 
	int n,num,rightest,meet; 
	while(scanf("%d", &n)!=EOF) 
	{ 
		lis[0]=-1; 
		rightest=0; 
		while(n--) 
		{ 
			scanf("%d",&num);
			meet=binarysearch(0,rightest,num); //找到填入数据的位置
			lis[meet]=num;
			if(meet>rightest) //若返回的位置比原来的大,那么记录最右边位置的值加一
				rightest++; 
		} 
		if (!rightest) 
			rightest=1; 
		printf("%d\n",rightest); 
	} 
}

  

posted @ 2010-04-07 13:16  SubmarineX  阅读(468)  评论(0编辑  收藏  举报