zoukankan      html  css  js  c++  java
  • 最长上升子序列(LIS)及其优化O(nlongn)

    1.求最长上升子序列:

    1.1 思路:用一个数组d记录到i位置的最长上升子序列d(i),那么第j个位置上的值就可以用前j-1个值来更新,时间复杂度O(N^2)。

    1.2 代码实例:

    int d[100005];
    int LIS(int A[],int n){
    	memset(d,0,sizeof d);
    	for(int i = 0;i < n;i++){
    		d[i] = 1;
    		for(int j = 0;j < i;j++){
    			if(A[i] >= A[j])	d[i] = max(d[i],d[j]+1);
    		}
    	}
    //	cout << d[n-1] << endl;
    	return d[n-1];
    }

    2.优化:

    1.1 思路:这次用len来表示当前上升子序列的长度,d数组来存放对应LIS长度的最小末尾。

    • 例如:A = {1 5 3 4 7},那么d[1] = 1,d[2] = 3,d[3] = 4, d[4] = 7。(其中d[1]LIS长度为1,d[3]LIS长度为3,以此类推)

    对上述例子详解:

    1. 从i = 0开始,A[0] = 1,将它放在d[1],此时d[1] = 1,len = 1;
    2. i = 1时A[1] = 5,5大于d数组最后一个数d[1] = 1,将5放在d[1]的后面,也就是d[2],于是d[2] = 5,len=2;
    3. i = 2时A[2] = 3,从d数组中找到小于3的最大数,是d[1] = 1,那么就把3放在d[1]后面,于是d[2] = 3;
    4. i = 3,A[3] = 4,同2,放在d[3],len= 3;
    5. i = 4,A[4] = 7,同2,放在d[4],len = 4。

    1.2 代码实例:

    int d[100005];
    int b_search(int x,int s,int e){
    	while(s < e){
    		int mid = s+(e-s)/2;
    		if(d[mid] >= x)	e = mid;
    		else s = mid+1;
    	}
    	return s;
    }
    int LIS(int A[],int n){
    	memset(d,0,sizeof d);
    	int len = 1;
    	d[1] = A[0];
    	for(int i = 1;i < n;i++){
    		if(A[i] >= d[len])	d[++len] = A[i];
    		else{
    			int p = b_search(A[i],1,len);
    			d[p] = A[i];
    		}
    	}
    //	for(int i = 0;i < len;i++)	cout << d[i+1]<<" ";
    	return len;
    }
  • 相关阅读:
    docker内存和cpu调试
    docker网络之overlay
    docker网络之bridge
    kubernete的证书总结
    docker网络之macvlan
    理解kubernetes环境的iptables
    前端面试题和答案
    软件项目技术点(25)——提升性能之检测绘制范围
    setTimeout的实现原理以及setTimeout(0)的使用场景
    HTML5新特性之WebSocket
  • 原文地址:https://www.cnblogs.com/long98/p/10352203.html
Copyright © 2011-2022 走看看