动态规划问题(三)最长递增子序列长度(LIS)
问题描述
有一个数组,它内部的顺序是乱序的,现在要求你找出该数组中的最长的递增子序列长度。
例如:对于数组 {10, 20, 9, 33, 21, 50, 41, 60, 80},它的最长递增子序列为{10, 22, 33, 50, 60, 80},长度为 4
解决思路
DP 方案:
令 \(L(i)\) 表示在 \(i\) 位置最长的递增子序列长度.
当
0 < j < i并且arr[j] < arr[i]时,\(L(i)=1 + max(L(j))\) \((j \in [0, i])\)当
i == 0时, \(L(i) = 1\)因此,状态转移方程为
\[L(i)=\begin{cases}
1 + max(L(j)) & j \in [0, i] \\
1 & i = 0 \\
\end{cases}
\]
贪心策略和二分搜索:
- 定义一个数组,这个数组的元素是单调递增的。
- 贪心策略:每次遇到一个元素将它插入到预先定义的数组中,使得整个数组的增长是最 “缓慢”的。
- 由于插入后数组的元素元素是有序的,因此下次插入时可以使用二分查找进行替换。
实现
DP 方案的实现
public class Solution {
public static int lis(int[] array) {
int len = array.length;
if (1 == len) return 1; // 边界条件 int ans = 1; // 对任意的数组序列,最少的递增子序列长度至少为 1
int[] dp = new int[len];
dp[0] = 1;
for (int i = 1; i < len; ++i) {
dp[i] = 1;
// 从小于 i 的数组索引中找到最大的递增序列长度
for (int j = 0; j < i; ++j) {
if (array[i] > array[j])
dp[i] = Math.max(dp[i], dp[j] + 1);
} // 与当前的最大递增序列长度进行比较,得到最终的最长递增子序列长度
ans = Math.max(dp[i], ans);
} return ans;
}
}
贪心策略 + 二分搜索的实现
class Solution {
public int lis(int[] array) {
int len = array.length;
if (1 == len) return 1; // 边界条件检测 int ans = 1;
int[] dp = new int[len];
dp[0] = array[0]; // 存储有序插入结果
for (int i = 1; i < len; ++i) {
// 如果当前元素大于定义数组的最大元素,则直接添加它到末尾
if (array[i] > dp[ans - 1]) {
dp[ans++] = array[i];
} else {
// 查找当前元素的插入位置
int lo = 0, hi = ans - 1, pos = 0;
while (lo <= hi) {
int mid = lo + (hi - lo) / 2;
if (dp[mid] == array[i]) {
pos = mid;
break;
} else if (dp[mid] > array[i]) {
hi = mid - 1;
} else {
lo = mid + 1;
pos = lo;
}
} dp[pos] = array[i];
}
} return ans;
}
}
动态规划问题(三)最长递增子序列长度(LIS)的更多相关文章
- POJ 2533 - Longest Ordered Subsequence - [最长递增子序列长度][LIS问题]
题目链接:http://poj.org/problem?id=2533 Time Limit: 2000MS Memory Limit: 65536K Description A numeric se ...
- 动态规划----最长递增子序列问题(LIS)
题目: 输出最长递增子序列的长度,如输入 4 2 3 1 5 6,输出 4 (因为 2 3 5 6组成了最长递增子序列). 暴力破解法:这种方法很简单,两层for循环搞定,时间复杂度是O(N2). 动 ...
- 求解最长递增子序列(LIS) | 动态规划(DP)+ 二分法
1.题目描述 给定数组arr,返回arr的最长递增子序列. 2.举例 arr={2,1,5,3,6,4,8,9,7},返回的最长递增子序列为{1,3,4,8,9}. 3.解答 ...
- 最长递增子序列(LIS)(转)
最长递增子序列(LIS) 本博文转自作者:Yx.Ac 文章来源:勇幸|Thinking (http://www.ahathinking.com) --- 最长递增子序列又叫做最长上升子序列 ...
- 最长递增子序列(LIS)
最长递增子序列(Longest Increasing Subsequence) ,我们简记为 LIS. 题:求一个一维数组arr[i]中的最长递增子序列的长度,如在序列1,-1,2,-3,4,-5,6 ...
- 最长递增子序列问题—LIS
问题:给定一组数 a0,a0,....,an-1. 求该序列的最长递增(递减)序列的长度. 最长递增子序列长度的求法有O(n^2)和O(nlogn)两种算法. 1.复杂度为O(n^2)的算法. 设L[ ...
- 最长公共子序列(LCS)、最长递增子序列(LIS)、最长递增公共子序列(LICS)
最长公共子序列(LCS) [问题] 求两字符序列的最长公共字符子序列 问题描述:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字 ...
- [51Nod 1218] 最长递增子序列 V2 (LIS)
传送门 Description 数组A包含N个整数.设S为A的子序列且S中的元素是递增的,则S为A的递增子序列.如果S的长度是所有递增子序列中最长的,则称S为A的最长递增子序列(LIS).A的LIS可 ...
- 动态规划(DP),最长递增子序列(LIS)
题目链接:http://poj.org/problem?id=2533 解题报告: 状态转移方程: dp[i]表示以a[i]为结尾的LIS长度 状态转移方程: dp[0]=1; dp[i]=max(d ...
- 动态规划之最长递增子序列(LIS)
在一个已知的序列{ a1,a2,……am}中,取出若干数组成新的序列{ ai1, ai2,…… aim},其中下标 i1,i2, ……im保持递增,即新数列中的各个数之间依旧保持原数列中 ...
随机推荐
- C语言条件运算符(?:)
条件运算符(conditional operator)有时候也称为三元运算符(ternary operator,或者trinary operator),因为它是唯一需要 3 个操作数的运算符: 条件 ...
- 形象描绘TCP三次握手和四次挥手
一.TCP三次握手TCP 三次握手就好比两个人在街上隔着50米看见了对方,但是因为雾霾等原因不能100%确认,所以要通过招手的方式相互确定对方是否认识自己.形象描绘TCP三次握手和四次挥手 张三首先向 ...
- 【翻译】listener.ora
今天仔细过一遍oracle的监听配置文件描述. cat $ORACLE_HOME/network/admin/samples/listener.ora # copyright (c) 1997 by ...
- [AHOI2002] Kitty猫基因突变
我们不妨将所有权值打到一棵树上,这很容易想到. 考虑暴力,如果我们选择了 \(w\) 个点,修改后我们会从叶子节点依次合并去计算贡献. 很显然我们可以动态规划维护. \(f[p][w][0/1/2]\ ...
- SpringBoot自动配置原理解析
1: 什么是SpringBoot自动配置 首先介绍一下什么是SpringBoot,SpringBoost是基于Spring框架开发出来的功能更强大的Java程序开发框架,其最主要的特点是:能使程序开发 ...
- Ubuntu 编辑文件、安装、删除软件等常用命令(持续更新)
一.编辑文件 1. sudo vi 文件名,进入文件页面,如图: 2. 按 i 键或者 o 键,进入编辑,左下角出现---------INSERT---------信息 3. 输入完毕后,按ESC退出 ...
- [Jetson Nano]SSH连接Jetson Nano时出现Xlib: extension NV-GLX missing on display localhost:10.0
解决SSH连接Jetson Nano时遇到的"Xlib: extension "NV-GLX" missing on display 'localhost:10.0'&q ...
- 《最新出炉》系列初窥篇-Python+Playwright自动化测试-31-JavaScript的调用执行-上篇
1.简介 在做web自动化时,有些情况playwright的api无法完成以及无法应对,需要通过或者借助第三方手段比如js来完成实现,比如:去改变某些元素对象的属性或者进行一些特殊的操作,本文讲解pl ...
- C语言已知四位数3025具有一个特殊性质:它的前两位数字30与后两位数字25之和是55,而55的平方正好等于3025。编程找出所有具有这种性质的四位数。
#include<stdio.h> void main() { int n, i, j; for (n = 1000; n < 10000; n++) { i = n / 100; ...
- python进程状态
思考 为啥我VS编辑器里一直在import中报错,但是写到笔记本里就可以直接用 之前俄罗斯方块也是同样问题 安装 pip install transitions 代码 from transitions ...