码迷,mamicode.com
首页 > 其他好文 > 详细

动态规划-最长递增子序列

时间:2020-03-25 19:40:12      阅读:69      评论:0      收藏:0      [点我收藏+]

标签:技术   port   www   使用   数据   mamicode   比较   一个   href   

1、问题:给出长度为N的数组,找出这个数组的最长递增子序列。 (递增子序列是指,子序列的元素是递增的) 

递推公式:

技术图片

 

 

2、原理分析:假设开始计算位置i,当位置i之前的所有记录都 大于位置i的值时,L(i)  = 1; 当存在小于L(i)的位置时,比较所有情况,取最大值,L(i) = L(k)+1。

 

3、code:

 

  (1)使用一维数据记录每个位置的最大上升子序列长度:keep[i] = L(i);

   

import java.util.Scanner;

/*
 * 求最长上升子串
 */
public class Main10_1 {
	public static void main(String args[] ) {
		Scanner s = new Scanner(System.in);
		int ar[] = {2,1,8,9,3,5,6};
		int len = ar.length;
		int keep[] = new int[len];
		int temp;
		int max = 1;
		keep[0] = 1;
		
		for(int i=1;i<len;i++) {
			int j;
			int count = 0;
			for(j=i-1;j>=0;j--) {
				//一点小变化,增加比较的次数
				//找到第一个小于ar[i]的值
				for(;(j>=0 && ar[j]>=ar[i]);j--);
				if(j>=0) {
					count = keep[j];
					temp = ar[j];
					for(j=j-1;j>=0;j--) {
						//等价于每个子序列只计算一次(末尾元素降序)
						if(ar[j]<ar[i] && ar[j]>temp) {
							temp = ar[j];
							count = Math.max(count,keep[j]);
						}
					}
				}
				/*
				最原始的方法,存在多余的计算
				if(ar[j]<ar[i]) {
					count = Math.max(count, keep[j]);
				}*/
			}
			keep[i] = count+1;
			max = max>keep[i]?max:keep[i];
		}
		for(int i=0;i<len;i++) {
			System.out.print(keep[i]+" ");
		}
		
		System.out.println("\n"+max);
	}
}

  (2)使用一位数组记录到达长度的最小元素:keep[i] = A(k){ 0<=k <= i} ,更小的值存在更大的概率与后续值构成升序序列。

    》从而记录数组天然构成一个升序序列,可以使用二分查找

package yrc2;

import java.util.Scanner;

public class Main10_2 {
	public static void main(String args[] ) {
		Scanner s = new Scanner(System.in);
		int ar[] = {2,1,8,9,3,5,6};
		int len = ar.length;
		int keep[] = new int[len+1];
		int keep_len = 1;
		keep[1] = ar[0];
		
		for(int i=1;i<len;i++) {
			int left = 1;
			int right =keep_len;
			while(left<=right) {
				int mid = (left+right)/2;
				if(keep[mid]<ar[i]) {
					left=mid+1;
				}else {
					/*
					 * 当keep[mid]==ar[i]也执行right = mid-1,
					 * 导致后续操作只会执行第一个if,最终left>right退出
					 * 并且left位置就是相等时mid的位置
					 */
					right = mid-1;
				}
				
			}
			keep[left] = ar[i];
			if(left>keep_len) {
				keep_len++;
			}
		}
		for(int i=1;i<=keep_len;i++) {
			System.out.print(keep[i]+" ");
		}
		System.out.println("\n"+keep_len);
	}

}

博客参考:https://www.jianshu.com/p/b3580d3e4dab

 

动态规划-最长递增子序列

标签:技术   port   www   使用   数据   mamicode   比较   一个   href   

原文地址:https://www.cnblogs.com/dream-flying/p/12567831.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!