《动态规划_入门 LIS 问题 》

时间:2022-07-25
本文章向大家介绍《动态规划_入门 LIS 问题 》,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

问题描述

问题 A: 最长上升子序列

时间限制: 2 Sec 内存限制: 64 MB

提交: 461 解决: 236

[提交][状态][讨论版][命题人:外部导入]

题目描述

一个数列ai如果满足条件a1 < a2 < ... < aN,那么它是一个有序的上升数列。我们取数列(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个自然数ai,0 <= ai <= 10000,两个数之间用空格隔开。

输出

输出只有一行,包含一个整数,表示最长上升子序列的长度。

样例输入

7
1 7 3 5 9 4 8

样例输出

4





解题思路:   

思路:

  1.定义长度为n的dp数组,dp[i]表示为arr[i]结尾的最长递增子序列的长度。

  2.对于第一个数arr[0]来说dp[0]=1,依次求出以i结尾的最长递增子序列

  3.对于dp[i],求arr[i]结尾的最长递增子序列,在arr[0..i-1]中选出比arr[i]小且长度最长的

  dp[j] , dp[i] = Math.max( dp[0…i-1] , dp[i] );如果所有的 dp[0…i-1] 都比 dp[i] 大,则 dp[i]=1;

  所有的结果求出来后 遍历 dp数组,从dp数组中查找到最大的数值:

Java 实现代码

 1 import java.util.Scanner;
 2 
 3 public class Main {
 4 
 5     public static int longestIncreasingSubsequence(int array[]) {
 6         // 判断数组是否为空,或者长度是否为 0
 7         if (array.length == 0 || array == null) {
 8             return 0;
 9         }
10         int len = array.length;
11 
12         // 新申请一个数组,用来存放第 i 个位置的 最长公共子串是多少
13         int[] dp = new int[len];
14         // 最少能保证 第一个长度为1
15         dp[0] = 1;
16 
17         for (int i = 1; i < len; i++) {
18             dp[i] = 1;
19             for (int j = 0; j < i; j++) {
20 
21                 if (array[i] > array[j]) {
22                     dp[i] = Math.max(dp[i], dp[j] + 1);
23                 }
24             }
25 
26         }
27 
28         int longest = Integer.MIN_VALUE;
29 
30         for (int i = 0; i < array.length; i++) {
31             longest = Math.max(dp[i], longest);
32         }
33         return longest;
34     }
35 
36     public static void main(String[] args) {
37         Scanner cin = new Scanner(System.in);
38         while (cin.hasNext()) {
39             int n = cin.nextInt();
40             int array[] = new int[n];
41 
42             for (int i = 0; i < n; i++) {
43                 array[i] = cin.nextInt();
44             }
45 
46             int result = longestIncreasingSubsequence(array);
47             System.out.println(result);
48         }
49     }
50 
51 }