zoukankan      html  css  js  c++  java
  • 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); 
    	} 
    }
    

      

  • 相关阅读:
    WCF进阶01 服务配置
    资源学习备忘 04
    .NET IoC主流框架 01:Castle Windsor Registering components onebyone
    IIS URL重写模块和ASP.NET路由组件比较
    资源学习备忘 03
    开源组件DockPanel Suite使用
    Dockable Window开源组件分享
    WCF进阶02 服务承载
    Prometheus 初探和配置(安装测试)
    TF31003错误的解决办法
  • 原文地址:https://www.cnblogs.com/submarinex/p/1941271.html
Copyright © 2011-2022 走看看