最长上升子序列 LIS

LIS最长上升子序列详解(动态规划、贪心+二分、树状数组) 1.摘要: 关于LIS部分,本篇博客讲一下LIS的概念定义和理解,以及求LIS的三种方法,分别是O(n^2)的DP,O(nlogn)的二分+贪心法,以及O(nlogn)的树状数组优化的DP,最后附上几道非常经典的LIS的例题及分析。 2.LIS的定义: 最长上升子序列(Longest Increasing Subsequence),简称LIS,也有些情况求的是最长非降序子序列,二者区别就是序列中... 阅读详情
题目:

http://acm.nyist.net/JudgeOnline/problem.php?pid=17

http://poj.org/problem?id=2533

两道题几乎一样,只不过对于输入输出的要求有所不同罢了。

LIS有两种方法:

一、第一种方法 · 时间复杂度为O(n^2):

状态:dp[i] := 区间为0~i的序列的LIS

转移方程:dp[i] = max(1, dp[k] + 1)  (0<=k<i && s[k]<s[i])

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string> 
using namespace std;

char s[10005];
int dp[10005];

int main ()
{
    int n;
    scanf("%d", &n);
    while(n--) {
        scanf("%s", &s);
        int len = strlen(s);
        for(int i=0; i<len; i++) {
            dp[i] = 1;
            for(int j=0; j<i; j++) {
                if(s[j] < s[i]) {
                    dp[i] = max(dp[i], dp[j]+1);
                }
            }
        }
        int ans = 0;
        for(int i=0; i<len; i++)    ans = max(ans, dp[i]);
        printf("%d\n", ans);
    }
    
    return 0;
}

 
二、第二种方法 · 时间复杂度为O(nlgn):

这种方法需要用二分查找查询到当前这一位元素应该是长度为多少的上升子序列的最后一位。

状态定义:dp[i] := 长度为i的上升子序列的当前最小的末尾元素,这里之所以要找最小的末尾元素,是因为越小越容易在后面加上一个稍大的元素使得找到的LIS更长!换句话说,倘若我已经将末尾元素的值设置为最低,尽力减小后来者的“门槛”了,但长度仍然只有这么多,那么上升子序列的最长长度也就只能是这样了。

举个例子:序列S为{1,4,2}

step1:将数组dp初始化为{+∞,+∞,+∞}

step2:开始遍历序列S

  ① 当前遍历到的元素为1时,我们在dp序列进行二分查找,寻找第一个大于等于1的元素的下标,我们找到dp[1]=+∞是第一个大于1的元素(dp的下标从1开始),于是dp[1]=1,即:目前来看,长度为1的上升子序列的末尾元素为1

  ② 当前遍历到的元素为4时,在dp序列中找到第一个大于等于4的元素为dp[2]=+∞,所以dp[2]=4。这时,dp={1,4,+∞,+∞},说明长度为1和2的上升子序列的最小末尾元素都已经找到。

  ③ 当前遍历到的元素为2时,在dp序列中找到第一个大于等于2的元素为dp[2]=4,这说明元素2没有办法让目前的最长上升序列更长(除非>4),但是相对于它后面的元素而言,它更有“潜质”作为长度为2的上升子序列的末尾元素,因为它比当前的4要小,4能做到的它都可以,而且可能得到比4更长的上升序列,即做得还可能比4要好。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string> 
#include <algorithm>
#define INF 30
using namespace std;

char s[10005];
int dp[10005];

int main ()
{
    int n;
    scanf("%d", &n);
    while(n--) {
        scanf("%s", &s);
        int len = strlen(s);
        for(int i=0; i<len; i++) {
            dp[i] = INF;
        } 
        for(int i=0; i<len; i++) {
            *lower_bound(dp, dp+len, s[i]-'a') = s[i]-'a';
        }
        printf("%d\n", lower_bound(dp, dp+len, INF) - dp);
    }
    
    return 0;
}
最长上升子序列(LIS)洛谷 题目描述:   传送门 题解思路:和最长公共子序列一样,LIS也是一个经典的dp问题。动规的常见套路是将原问题化简成多个形式相同的子问题。这里求序列的最长上升子序列长度,首先求以ai(ai是序列中的元素,1<=i<=n)结尾的最长上升子序列长度,再从这些以ai结尾的最长子序列长度中选择一个最长的作为整个序列的最长上升子序列长度。 核心算法: 假设maxlen(i)表示以ai为终点的最长上升子序列长度,则有: 初始状态maxlen(1)=1(因为以a1为终点的上升序列就只有a1自己) maxlen 阅读详情

相关推荐

一文带你完成ARMv8架构中的cache知识点

【摘要】 在最初开发ARM架构时,处理器的时钟速度和内存的访问速度大致相同。今天的处理器内核要复杂得多,其时钟速度可以快上几个数量级。但是,外部总线和内存设备的频率并没有扩大到同样的程度。有可能实现小块的片上SRAM,它可以以与内核相同的速度运行,但是与标准的DRAM块相比,这种RAM非常昂贵,因为后者的容量可以达到数千倍。在许多基于ARM处理器的系统中,访问外部存储器需要几十甚至几百个内核周期。 cache的技术背景 在最初开发ARM架构时,处理器的时钟速度和内存的访问速度大致相同。今天的处.

ABCCloud的博客 1853

LIS(最长上升子序列长度)

https://vijos.org/p/1028 #include #include #include #include using namespace std; #define logic(a,b) (strstr((a),(b)) == (a)) char s[2001][75]; int main(){ int n; cin>>n; for (int i = 0;

梦醒了 1251

离散数学期末考试试卷(两套)-熟悉题型

3.设集合A={a,b,c,d}上有自反关系R={,,,,},对称关系S={,,,}。6.设集合A={1,2,3},B={u,v,w},C={a,b,c},f是集合A到集合B上的映射,g是集合B到集合C上的映射,f={, , },g={},则复合函数g。5. 设集合A={a,b,c,d,e},下列选项中哪一个集合不是A的划分( )。

muse3159546973的博客 6956

最长递增子序列。给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。(PHP、GO)

给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。 子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。 示例 1: 输入:nums = [10,9,2,5,3,7,101,18] 输出:4 解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。 示例 2: 输入:nums = [0,1,0,3,2,3] 输出:4 示例 3: 输入:nums = [7,7,7,7,7

wyisgoodman的博客 2777

5分钟搞定PettingZoo多智能体环境搭建:从安装到运行第一个Demo

本文详细介绍了如何在5分钟内完成PettingZoo多智能体环境的搭建,从安装到运行第一个Demo。通过精准的版本控制和常见问题解决方案,帮助开发者快速上手多智能体强化学习(MARL)环境配置,并提供了实战案例和性能优化技巧。

backprop5master的博客 221

Unity 游戏实例开发集合 之 Car Racing 2D (2D赛车) 休闲小游戏快速实现

Unity 游戏实例开发集合 之 Car Racing 2D (2D赛车) 休闲小游戏快速实现 目录 Unity 游戏实例开发集合 之 Car Racing 2D (2D赛车) 休闲小游戏快速实现 一、简单介绍 二、Car Racing 2D (2D赛车) 游戏内容与操作 三、相关说明 四、游戏代码框架 五、知识点 六、游戏效果预览 七、实现步骤 八、工程源码地址 九、延伸扩展 一、简单介绍 Unity 游戏实例开发集合,使用简单易懂的方式,讲解常见游戏的开发实现过程,方便

仙魁XAN 7701

LIS算法: 最长上升子序列

LIS定义 LIS(Longest Increasing Subsequence)最长上升子序列 一个数的序列bi,当b1 < b2 < … < bS的时候,我们称这个序列是上升的。对于给定的一个序列(a1, a2, …, aN),我们可以得到一些上升的子序列(ai1, ai2, …, aiK),这里1 <= i1 < i2 < … < iK <= N。 比如,对于序列(1, 7,

wbin233的博客 2万+

QGis软件 —— 9、QGis - 由点绘制热力图来模拟人流量(绘制点方式、excel导入数据方式)

QGis软件 —— 9、QGis - 由点绘制热力图来模拟人流量(绘制点方式、excel导入数据方式)

1469

都能看懂的LIS(最长上升子序列)问题

LIS问题介绍: 首先来说一下什么是LIS问题: 有一个长为n的数列a0, a1, ......, a(n-1)。请求出这个序列中最长的上升子序列的长度。上升子序列指的是对于任意的i<j都满足ai<aj的子序列,该问题被称为最长上升子序列(LIS,Longest Increasing Subsequence)的著名问题。 举个栗子:给你一个序列为(1,5 ,2,6,9,1...

ltrbless的博客 4万+

基于GEC6818开发板+Linux+Qt设计的智能养老院出入管理系统(195)

当前,传统的养老院出入管理模式普遍存在信息更新滞后、数据统计繁琐、实时监控能力不足等问题,难以满足现代养老机构对安全管理与服务质量提升的需求。本系统设计正是针对这些问题,通过集成先进的硬件设备如高性能GEC6818开发板以及RFID刷卡模块,结合稳定高效的嵌入式Linux操作系统和QT开发框架,构建一套功能齐全、操作直观、响应迅速的智能出入管理系统。 该系统能自动记录并实时显示老人的进出时间,方便管理人员及时了解每位老人的活动轨迹,同时具备强大的后台管理功能,支持管理员便捷地进行老人信息的增删改查操作。通

1069

基于simulink构建一个完整的航空航天器姿态控制与导航仿真模型

航空航天器的姿态控制与导航系统是确保飞行器稳定运行和精确执行任务的核心技术。其目标是通过传感器获取飞行器的状态信息,并利用控制器调整飞行器的姿态,使其按照预定轨迹飞行。基于MATLAB/Simulink平台进行航空航天器姿态控制与导航系统的建模与仿真,可以帮助研究者验证算法性能并优化系统的动态响应。本项目旨在构建一个完整的航空航天器姿态控制与导航仿真模型,包括飞行器动力学建模、传感器模块设计、控制器实现以及导航算法仿真,并通过仿真分析其性能。

xiaoheshang_123的博客 272

线性DP LIS 最长上升子序列

为:读入a[i],从1到n利用循环记录dp[i],如果当前的a[i]大于a[j],那就意味着a[i]可以加入到以a[j]结尾的子序列中,在这种情况下我们可以更新dp[i]的值,取dp[i]和dp[j]+1的最大值(加1表示在a[j]的基础上添加a[i]至末尾)。:f[i]代表以a[i]为终点的最长上升子序列,g[i]代表以a[i]为起点的最长下降子序列,因为在f[i]和g[i]都计算了一次a[i],所以要减去1,求和-1之后的数量就是以某个元素为转折点的先上升后下降的长度。例如1 2 4 1 3 4。

2301_80170790的博客 1429

Matlab之App Designer 如何进行三维图形绘制教程

基于Matlab中的App Designer设计可视化界面并进行数据导入及3D绘图,可以直观的在可视化界面上展示分析结果,方便用户进行图形的操作。本文采用案例讲解的方式,详细介绍了如何采用Matlab App Designer建立数据3D绘图的GUI可视化界面的方法和详细的过程步骤,并介绍了导入数据进行计算时需要注意的相关事项,同时提供了详细的代码,以便读者进行学习和操作。

m0_59012156的博客 2066

LIS最长上升子序列

给定一个数组,让你找出一个最长上升子序列的长度,例如[1,4,6,2,3,5] 答案为4:[1,2,3,5]。 我们用DP[i]表示以下标为i的元素结尾的子序列的最长上升子序列长度 代码如下: ll p[10010]; ll dp[10010]; int main() { ll n, ans = 0; cin >> n; for (int i = 1; i <= n; i++) cin >> p[i]; for (int i =

陈颜的博客 5640

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

最长上升子序列(LIS)

1LIS的定义: 最长上升子序列(Longest Increasing Subsequence),简称LIS,也有些情况求的是最长非降序子序列,二者区别就是序列中是否可以有相等的数。 2思路: 我们都知道,动态规划的一个特点就是当前解可以由上一个阶段的解推出, 由此,把我们要求的问题简化成一个更小的子问题。子问题具有相同的求解方式,只不过是规模小了而已。最长上升子序列就符合这一特性。我们要求n个...

sherry_zhen的博客 453

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

LIS-最长上升子序列

LIS(最长上升子序列)是一个经典的问题。首先我们来介绍子序列的概念:子序列指的是一个序列中,按照原顺序选出若干个不一定连续的元素所组成的序列。LIS有两种算法模型:一种是复杂度为的dp模型,另外一种是复杂度为,利用二分实现的模型。

m0_72972329的博客 872

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

dp——最长上升子序列(LIS)

问题描述 最长上升子序列LIS(longest increasing subsequence):给定一个长度为n的序列 (a1,a2,a3,...,an) a1<a2<a3<...<an 从中选取一个子序列,这个子序列需要单调递增。 问最长上升子序列(LIS)的长度。 eg:1, 5, 2, 4, 11, 7, 9 其中的一些上升子序列为{1,5},{1,...

qq_41972012的博客 264

最长上升子序列(提高LIS之有限制的LIS训练)

目录 题目 解析 朴素LIS lower_bound优化LIS 包含第k个元素的LIS及优化 “二分”求解 从前至后依次求解 题目 题目描述 给出一个长度为N的整数序列,求出包含它的第K个元素的最长上升子序列。 输入 第一行两个整数N, K,第二行N个整数 输出 如题目所说的序列长度。 样例输入 8 6 65 158 170 299 300 155 207 389...

fsy的博客 666

最长上升子序列(LIS)

概述: 关于LIS部分,本篇博客讲一下LIS的概念定义和理解,以及求LIS的三种方法,分别是O(n^2)的DP,O(nlogn)的二分+贪心法,以及O(nlogn)的树状数组优化的DP,最后附上几道非常经典的LIS的例题及分析。 1.动态规划 我们要求n个数的最长上升子序列,可以求前n-1个数的最长上升子序列,再跟第n个数进行判断。求前n-1个数的最长上升子序列,可以通过求前n-2个数的最长上升子序列……直到求前1个数的最长上升子序列,此时LIS当然为1。 让我们举个例子:求 2 7 1 5 6 4 3 8

小飞猪的博客 387

LIS(最长上升子序列)

方法一: dp动态规划 状态设计:dp[i]代表以a[i]结尾的LIS的长度  状态转移:dp[i]=max(dp[i], dp[j]+1) (0&lt;=j&lt; i, a[j]&lt; a[i])  时间复杂度:O(N^2)  例题:https://blog.csdn.net/y201619819/article/details/78354348   方法二:贪心+二分 时间复杂...

雨羊的博客 515

最长上升子序列 (LIS)

1.LIS的定义: 最长上升子序列(longest increasing subsequence),也可以叫最长非降序子序列,简称LIS,不是太难。即一个数的序列bi,当b1 < b2 < … < bS的时候,我们称这个序列是上升的。对于给定的一个序列(a1, a2, …, aN),我们可以得到一些上升的子序列(ai1, ai2, …, aiK),这里1 <...

weixin_30594001的博客 273

LIS--最长上升子序列

最长上升子序列,又称LIS,是动态规划的一个经典应用。 在原序列取任意多项,不改变它们在原来数列的先后次序,得到的序列称为原序列的子序列。最长上升子序列,就是给定序列的一个最长的、数值从低到高的子序列,最长上升子序列不一定是唯一的。 输入样例: 8 2 1 5 3 6 4 6 3 输出样例: 4 解释:它的最长上升子序列为1,3,4,6和2,3,4,6,长度均为4 ...

qq_41706331的博客 248

DP经典问题LIS——最长上升子序列

1.问题描述: 2.算法分析: 因为是初学,只学习了O(N^2)的算法复杂度。 最后,我们将dp数组的最大值是最长上升子序列的长度。 推荐一篇文章包含了O(nlogn)的LIS算法。 LIS推荐 3.源代码: #include &lt;iostream&gt; #include &lt;cstring&gt; using namespace std; int dp[101], a[101],...

ly's Blog 588

算法强化 —— 最长上升子序列 LIS

最长上升子序列 LIS 给定一个无序的整数数组,找到其中最长上升子序列的长度。 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。 暴力解法 列出所有子序列,再判断这个子序列是不是上升子序列 状态和状态转移方程 状态: 定义dp[i],表示以第i个数字为结尾的最长上升子序列的长度 dp[i]表示范围[0,i]...

qq_33357094的博客 213
上一篇: POJ 1141 —— Brackets Sequence
下一篇: NYOJ 23 —— 取石子(一)【博弈】
AcIsFun
博客等级 码龄10年 1粉丝 92原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值