最长上升子序列

来源:互联网 发布:mac怎么做苹果铃声 编辑:程序博客网 时间:2024/05/16 09:46

问题描述:一个数的序列ai,当a1 < a2 < ... < aS的时候,我们称这个 序列是上升的。对于给定的一个序列(a1, a2, ..., aN),我们可 以得到一些上升的子序列(ai1, ai2, ..., aiK),这里1 <= i1 < i2 < ... < iK <= N。比如,对于序列(1, 7, 3, 5, 9, 4, 8), 有它的一些上升子序列,如(1, 7), (3, 4, 8)等等。这些子序 列中最长的长度是4,比如子序列(1, 3, 5, 8).  你的任务,就是对于给定的序列,求出最长上升子序列的长度。

输入数据

输入的第一行是序列的长度N (1 <= N <= 1000)。第二行给出 序列中的N个整数,这些整数的取值范围都在0到10000。

输出要求 最长上升子序列的长度。

输入样例 7 1 7 3 5 9 4 8

输出样例 4

思路:必须确定一个序列的终点,即求以该序列为终点的上升子序列的长度。所以,我们遍历的其实是每一个终点,每一个不同的终点即是一个不同的状态。如果要求以第S个数为终点的最长上升子序列,则必然要根据前面的第s-1个数,看前s-1个数中所包含的上升子序列最长的是多少,到第S个数就是前s-1个中最长的那个+1即可,以此类推。因此有代码:

import java.util.Arrays;import java.util.Scanner;public class longest_up_subq {public static void main(String args[]) {Scanner scan=new Scanner(System.in);int n=scan.nextInt();int []a=new int[n+1];int []max_len=new int[n+1];for(int i=1;i<=n;i++)max_len[i]=1;for(int i=1;i<=n;i++)a[i]=scan.nextInt();for(int i=1;i<=n;i++) {for(int j=1;j<n;j++) {if(a[i]>a[j]) max_len[i]=Math.max(max_len[j]+1, max_len[i]);}}Arrays.sort(max_len);System.out.println(max_len[n]);}}

还有一种思路,从左到右遍历每一个状态时,同步更新后面的每一个节点可能的最长上升子序列的长度,因为后面节点的上升子序列长度是根据前面的节点来确定的,所以经过比较之后一定会被赋值一个最长的上升子序列的长度给后面的节点,因此在递归部分可以有如下代码:

                for(int i=1;i<=n;i++) {for(int j=i+1;j<=n;j++) {if(a[j]>a[i])max_len[j]=Math.max(max_len[i]+1, max_len[j]);}}