- > 动规讲解基础讲解七——最长单增子序列
(LIS Longest Increasing Subsequence)给定一个数列,从中删掉任意若干项剩余的序列叫做它的一个子序列,求它的最长的子序列,满足子序列中的元素是单调递增的。
例如给定序列{1,6,3,5,4},答案是3,因为{1,3,4}和{1,3,5}就是长度最长的两个单增子序列。
处看此题,怎么做? 万能的枚举?枚举全部2^n个子序列,找出最长的,固然可以,就是复杂度太高。我们为什么要枚举呢?因为要知道取了哪些数,其实我们只需要考虑上一个数和取了几个数就可以了吧?因为单增的意思是比前一个数大,我们要加入这个数的时候,只考虑它比之前加入的最后一个数大就可以了。而最长的意思是数的个数最多,我们只要知道数的总个数就可以了,没必要知道具体有哪些数。
让我们尝试一下用动态规划的思考办法。首先设置数列是a1, a2, a3…an,为了方便我们加入一项a0=-∞,后面我们将发现这会给我们带来极大的方便。int f[i]表示以第i个数结尾的最长单调子序列的长度, 那么我们看一下加入ai之前的最后一个数是aj,显然j < i并且aj < ai,我们有f(i) = f(j) + 1,因为往后面延长了一项嘛。那根据这个式子,我们显然应该选择最大的f(j),才能让f(i)最大。
于是我们有了递推关系f(i) = max{f(j)| j < i并且aj < ai} + 1,光有了递推关系还不够,初值呢? f(0) = 0,并且我们加入了a0=-∞,这样对每个i > 0,j总是存在的,大不了就达到下标0了嘛。
f[] = ;
for i = to n do
f[i] = ;
for j = to i – do
f[i] = max(f[i], f[j] + )
endfor
endfor
#include<cstdio>
#include<cstring>
using namespace std;
int n,a[],f[],maxn;
int main()
{
memset(f,-,sizeof(f));
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&a[i]);
for(int i=;i<=n;i++)
{
if(a[i]>f[maxn]) f[++maxn]=a[i];
else if(a[i]<f[maxn])
{
int l=,r=maxn;
while(l<=r)
{
int m=(l+r)/;
if(a[i]<f[m]) r=m-;
else if(a[i]==f[m]) break;
else l=m+;
}
if(f[l]>a[i]) f[l]=a[i];
}
}
printf("%d",maxn);
}
如果对你有所帮助,别忘了加好评哦;么么哒!!下次见!88
- > 动规讲解基础讲解七——最长单增子序列的更多相关文章
- 51nod 最长单增子序列(动态规划)
最长单增子序列 (LIS Longest Increasing Subsequence)给定一个数列,从中删掉任意若干项剩余的序列叫做它的一个子序列,求它的最长的子序列,满足子序列中的元素是单调递增的 ...
- - > 动规讲解基础讲解五——最长公共子序列问题
一些概念: (1)子序列: 一个序列A = a1,a2,……an,中任意删除若干项,剩余的序列叫做A的一个子序列.也可以认为是从序列A按原顺序保留任意若干项得到的序列. 例如: 对序列 1,3,5 ...
- - > 动规讲解基础讲解一——01背包(模板)
作为动态规划的基础,01背包的思想在许多动规问题中会经常出现,so,熟练的掌握01背包的思路是极其重要的: 有n件物品,第i件物品(I = 1,2,3…n)的价值是vi, 重量是wi,我们有一个能承重 ...
- - > 动规讲解基础讲解六——编辑距离问题
给定两个字符串S和T,对于T我们允许三种操作: (1) 在任意位置添加任意字符(2) 删除存在的任意字符(3) 修改任意字符 问最少操作多少次可以把字符串T变成S? 例如: S= “ABCF” ...
- - > 动规讲解基础讲解八——正整数分组
将一堆正整数分为2组,要求2组的和相差最小.例如:1 2 3 4 5,将1 2 4分为1组,3 5分为1组,两组和相差1,是所有方案中相差最少的. 整数个数n<=100,所有整数的和<=1 ...
- - > 动规讲解基础讲解四——最大子段和问题
给出一个整数数组a(正负数都有),如何找出一个连续子数组(可以一个都不取,那么结果为0),使得其中的和最大? 例如:-2,11,-4,13,-5,-2,和最大的子段为:11,-4,13.和为20. ...
- - > 动规讲解基础讲解四——矩阵取数
给定一个m行n列的矩阵,矩阵每个元素是一个正整数,你现在在左上角(第一行第一列),你需要走到右下角(第m行,第n列),每次只能朝右或者下走到相邻的位置,不能走出矩阵.走过的数的总和作为你的得分,求最大 ...
- - > 动规讲解基础讲解三——混合背包(背包模板)
将01背包,完全背包,和多重完全背包问题结合起来,那么就是混合三种背的问题 根据三种背包的思想,那么可以得到混合三种背包的问题可以这样子求解 for(int i=1; i<=N; ++i) if ...
- 最长公共子序列lcs 51nod1006
推荐参考博客:动态规划基础篇之最长公共子序列问题 - CSDN博客 https://blog.csdn.net/lz161530245/article/details/76943991 个人觉得上面 ...
随机推荐
- [转]c++中的string常用函数用法总结
标准c++中string类函数介绍 注意不是CString之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必 担心内存是否足够.字符串长度等等,而且作为 ...
- Spark学习之编程进阶——累加器与广播(5)
Spark学习之编程进阶--累加器与广播(5) 1. Spark中两种类型的共享变量:累加器(accumulator)与广播变量(broadcast variable).累加器对信息进行聚合,而广播变 ...
- oracle 手动配置服务器端和客户端
1.oracle 服务器端配置 将oracle安装完成之后,在Net Configuration Assistant配置 1.监听程序配置 先找到Net Configuration Assistant ...
- Laravel 网站项目目录结构规划
最近在用Laravel这个PHP框架搭网站,大致了解这个框架的目录结构之后感觉学到了不少东西. 首先安装好包管理器: PHP部分当然用composer,安装在全局目录下方便一点. 前端部分,我没有选择 ...
- Java 基础入门随笔(11) JavaSE版——继承、覆盖、抽象类
1.面向对象的特征二:继承 定义: 指一个对象直接使用另一对象的属性和方法. 继承好处: 1.提供代码的复用性. 2.让类与类直接产生了关系,给第三个特征多态提供了前提. java中支持单继承.不直接 ...
- 【windows】自动化测试持续集成(CI)环境部署
1. 环境准备 1.1 我的环境 1.Win10 64位 2.JDK 1.8.0_121 3.Tomcat 7.0.92 4. Jenkins 2.24 5.SVN-Server 3.8.1 1.2 ...
- CAD使用GetxDataDouble读数据(网页版)
主要用到函数说明: MxDrawEntity::GetxDataDouble2 读取一个Double扩展数据,详细说明如下: 参数 说明 [in] LONG lItem 该值所在位置 [out, re ...
- <MyBatis>入门二 全局配置文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC ...
- db2层级查询
CREATE VIEW v_orgtype99 asSELECT t1.SYS_ORG_TYPE_NAME top_name1, t2.SYS_ORG_TYPE_NAME top_name2, --若 ...
- http怎么做自动跳转https
Nginx版本 server { listen 80; server_name localhost; rewrite ^(.*)$ https://$host$1 permanent; ...