LIS
LIS是最长上升子序列。什么是最长上升子序列? 就是给你一个序列,请你在其中求出一段最长严格上升的部分,它不一定要连续。
就像这样:2, 3, 4, 7 和 2, 3, 4, 6 就是序列 2 5 3 4 1 7 6 的两个上升子序列,最长的长度是 4。
结果:
f[i]=max(f[i], f[j]+1);
思路:
其实这是一道动态规划的问题,最长不降子序列。
这道题类似于:https://blog.youkuaiyun.com/xiaodingqq/article/details/79641671,可以把这两道题一起来看。解题思路差不多的。
简单来说,也是相当于“累加”的过程。可以想象一下。哈哈
过程:
2 5 3 4 1 7 6
(下面的过程,箭头左边为序列,右边f[i]对应的下标赋值)
第一步:2 5 → 0 1
第二步:2 5 3 → 0 1 1 (因为2<3,所以3的f[2] + (2的f[0]+1)),加1是表示把“3”这个数加进去了
第三步:2 5 3 4 → 0 1 1 2 ( …… 因为3<3,所以4的f[3] + (3的f[2]+1)),加1是表示把“4”这个数加进去了
第四步:2 5 3 4 1 → 0 1 1 2 0 (…… 因为在1之前的序列中,没有比1再小了,所以只能保持默认的值0)
第五步:2 5 3 4 1 7 → 0 1 1 2 0 3
第六步:2 5 3 4 1 7 6 → 0 1 1 2 0 3 3
所以有两个上升子序列:2 3 4 7 和 2 3 4 6
代码如下:
import java.util.*;
import java.math.*;
public class Main {
public static final int N = 1000;
public static int[] f = new int[N];
public static int[] b = new int[N];
public static int max(int a, int b) {//返回最大值
if (a > b) {
return a;
}
return b;
}
public static int lis(int n) {
int res = 0;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < i; ++j) {
if (b[j] < b[i]) {//i 与 i前面的数j 进行比较
//+1:代表已经把i算进去了
f[i]=max(f[i], f[j]+1);//填空,动态规划
System.out.println(f[i]);
}
}
System.out.println();
res = max(res, f[i]);
}
return res+1;//最长的长度
}
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
int n = cin.nextInt();
for (int i = 0; i < n; ++i) {
b[i] = cin.nextInt() ;
}
System.out.println("result:"+lis(n));
}
}
300



被折叠的 条评论
为什么被折叠?



