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

      

  • 相关阅读:
    pm2进阶使用
    javascript装饰器模式
    pupeteer初体验
    重构:从Promise到Async/Await
    # electron-vue 尝试做个网易云音乐
    Kafka监控:主要性能指标
    生产环境Rabbitmq集群安装部署与配置
    Java同步块(synchronized block)
    RabbitMQ高可用镜像队列
    kafka-0.9消费者新API
  • 原文地址:https://www.cnblogs.com/submarinex/p/1941271.html
Copyright © 2020-2023  润新知