动态规划算法——最长上升子序列
今天我们要讲的是最长上升子序列(LIS)。
【题目描述】
给定N个数,求这N个数的最长上升子序列的长度。
【样例输入】
7
2 5 3 4 1 7 6
【样例输出】
4
什么是最长上升子序列? 就是给你一个序列,请你在其中求出一段不断严格上升的部分,它不一定要连续。
就像这样:2,3,4,7和2,3,4,6就是序列2 5 3 4 1 7 6的两种选取方案。最长的长度是4.

那么,怎么求出它的最大上升子序列长度为4呢?这里介绍两种方法,都是以动态规划为基础的。
首先,我们先介绍较慢 O(n2)O(n2) 的方法。我们记 fifi为到这个数为止,最长上升子序列的长度。

这种方法就是每一次尝试寻找“可以接下去的”那一个数,换句话说,设原序列为a,则
当aj<ai(j<i)aj<ai(j<i)且fj+1>fifj+1>fi时,fi=fj+1fi=fj+1。
对于每一个数,他都是在“可以接下去”的中,从前面的最优值+1转移而来。通俗的来说,你肯定就是在所有能找到的里面取最好的一个,不要白不要嘛。
因此,这个算法是可以求出正确答案的。复杂度很明显,外层i枚举每个数,内层j枚举目前i的最优值,即 O(n^2)。
package cn.tiger.funny; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * 动态规划算法——最长上升子序列 * @author jyuan * */ public class LIS { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); for (int i = 0; i < 20; i++) { list.add(i); } Collections.shuffle(list); //乱序 System.out.println(list); //[18, 8, 19, 11, 14, 16, 6, 13, 17, 12, 4, 1, 0, 3, 15, 2, 7, 10, 9, 5] System.out.println(lis(list)); //5 } private static int lis(List<Integer> list) { int[] num = new int[list.size()]; for(int i=0 ; i<list.size() ; i++) { num[i]=1; for(int j=0;j<i;j++) { if(list.get(j)<list.get(i) && num[j]>=num[i]) num[i]=num[j]+1; } } int max=0; for(int i=0 ; i<list.size() ; i++) if(max<num[i]) max=num[i]; return max; } }

浙公网安备 33010602011771号