先上一道例题:Bridging signals POJ - 1631

这道题第一反应就想到了 [CEOI96]渡轮问题 就是一个非常裸的求最长上升子序列的长度,还不要方案,非常的水。然而,常规的dp复杂度是 O(n^2) ,这道题会愉快地TLE,所以要进行nlogn级别的优化。

//O(n^2) TLE
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define LL long long
#define INF 0x3f3f3f3f
#define MAXN 40005
int n;
int a[MAXN],dp[MAXN];
int main()
{int T;scanf("%d",&T);while(T--){int ans=-1;scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",&a[i]);dp[i]=1;for(int j=1;j<i;j++)if(a[j]<a[i])dp[i]=max(dp[i],dp[j]+1);ans=max(ans,dp[i]);}printf("%d\n",ans);}return 0;
}
nlogn算法

其实说实话我觉得这个算法比常规的动归思想上更暴力,就是贪心地取,然而复杂度更小。

具体就是:

  • 定义d[k]:长度为k的上升子序列的最末元素,若有多个长度为k的上升子序列,则记录最小的那个最末元素。
  • 枚举a[i] 对每个a[i]:若a[i]>d[len],那么len++,d[len] = a[i];
  • 否则,从d[1]到d[len-1]中找到一个j,满足d[j-1] < a[i]< d[j],则根据d的定义,我们需要更新长度为j的上升子序列的最末元素,即 d[j] = a[i];

(这里实际上就是运用了贪心的思路,d[j-1]< a[i]< d[j]的条件保证了正确性,而对于d中的每一个元素,都尽力做到最小,这样就尽可能地使a[i]>d[len]成立)

//nlogn LIS
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define LL long long
#define INF 0x3f3f3f3f
#define MAXN 40005
int n;
int a[MAXN];
int d[MAXN];//长度为k的上升子序列的最末元素,若有多个,记录最小
int main()
{int T;scanf("%d",&T);while(T--){scanf("%d",&n);int len=1;scanf("%d",&a[1]);d[1]=a[1];for(int i=2;i<=n;i++){scanf("%d",&a[i]);if(a[i]>d[len])len++,d[len]=a[i];else {int pos=lower_bound(d+1,d+len+1,a[i])-d;d[pos]=a[i];}}printf("%d\n",len);}return 0;
}

【dp优化】LIS(最长上升子序列)长度的nlogn算法相关推荐

  1. 最长递增子序列的O(NlogN)算法

    假设存在一个序列d[1..9] = 2 1 5 3 6 4 8 9 7,可以看出来它的LIS长度为5. 下面一步一步试着找出它. 我们定义一个序列B,然后令 i = 1 to 9 逐个考察这个序列. ...

  2. lis最长上升子序列o(nlogn)优化

    LIS的暴力算法 我们知道,LIS(最长上升子序列,最长下降子序列,最长不上升子序列,最长不下降子序列)如果按照最初得方法做,我们设置的状态f[i]表示i结尾的最长LIS的长度,在枚举每一个数的时候都 ...

  3. LCS最长公共子序列和LIS最长上升子序列——例题剖析

    一.LCS最长公共子序列 最长公共子序列(LCS)问题算法详解+例题(转换成LIS,优化为O(nlogn),看不懂你来打我) longest comment subsequence 模板题 longe ...

  4. 算法设计 - LCS 最长公共子序列最长公共子串 LIS 最长递增子序列

    出处 http://segmentfault.com/blog/exploring/ 本章讲解: 1. LCS(最长公共子序列)O(n^2)的时间复杂度,O(n^2)的空间复杂度: 2. 与之类似但不 ...

  5. LIS最长上升子序列详解(动态规划、贪心+二分、树状数组)

    1.摘要: 关于LIS部分,本篇博客讲一下LIS的概念定义和理解,以及求LIS的三种方法,分别是O(n^2)的DP,O(nlogn)的二分+贪心法,以及O(nlogn)的树状数组优化的DP,最后附上几 ...

  6. 求最长上升子序列长度和输出序列

    最长上升子序列 Special Judge Description 求最长上升子序列. Input 单测试用例. 第一行是一个正整数n,0 < n ≤ 3000 第二行是n个非负整数. Outp ...

  7. 最长公共子序列长度的四种解法

    一.题目:求两个字符序列的最长公共字符子序列.给定两个字符串,求解这两个字符串的最长公共子序列(Longest Common Sequence).比如字符串1:BDCABA:字符串2:ABCBDAB, ...

  8. 最长公共子序列 【DP】+【最长公共子序列】

    最长公共子序列 时间限制: 3000 ms  |            内存限制: 65535 KB 难度: 3 描述 咱们就不拐弯抹角了,如题,需要你做的就是写一个程序,得出最长公共子序列. tip ...

  9. 求最长公共子序列长度

    求两个字符串的公共子序列 1.求最长公共子序列(子序列可以不连续) 这是一道动态规划题,设二维数组dp[i][j],dp[i][j]表示a串前i个字符(包括第i个)与b串前j个字符(包括第j个)所有的 ...

  10. 动态规划——最长公共子序列长度

    最长公共子序列长度是编辑距离的另外一种表示方法.只允许添加.删除字符两种惭怍.它表征的是两字符串之间的相似度. 解决思路是: 如果a[i]=b[j],则 公共子序列长度加1,继续考察a[i+1]和b[ ...

最新文章

  1. (转)Linux下C++开发初探
  2. linux添加审计账户_眼镜蛇W眼镜蛇白盒品白源代码审计工具 白帽子版
  3. AngularJS的学习笔记(一)
  4. sublime3安装package controller遇到的问题
  5. 1. 在虚拟机中 添加内容
  6. [LeetCode] Inorder Successor in BST 二叉搜索树中的中序后继节点
  7. ASP.NET程序中常用的三十三种代码一
  8. android javap命令生成自定义类签名
  9. 手把手教你申请Coursera的课程助学金
  10. Python开发环境的搭建(win7)
  11. ubuntu ble c语言编程,c – 如何在ubuntu上安装bluez进行开发?
  12. UA PHYS515A 电磁学II 静电学问题8 球坐标系中的Laplace方程与球谐函数
  13. matlab中grid的用法
  14. 八 Spring Security Oauth2 单点登录 第三方授权(QQ、微信登录)
  15. 魔兽世界怀旧服哪个服务器人最多,魔兽世界怀旧服8个服务器人口普查 部落/联盟阵营最新比例...
  16. 使用Intrinsics优化
  17. Linux 用户管理 文件目录指令 时间日期指令 搜索查找类 解压压缩类
  18. 什么是大数据 究竟多大才算是大数据,大数据怎么学习?
  19. 【实时数仓】DWD层需求分析及实现思路、idea环境搭建、实现DWD层处理用户行为日志的功能
  20. 英语四级作文模板(一)

热门文章

  1. R语言建立Cox回归模型(包含所有协变量)比较不同治疗方法生存率的差异(新样本数据)、 Kaplan-Meier 法拟合生存曲线直观地比较两种治疗方法下的生存率的变化、自定义线条类型lty参数
  2. 2019面试,笔试记录
  3. 【回顾】Spring中使用了哪些设计模式
  4. 『2023北京智源大会』大模型新基建与智力运营论坛
  5. STM32 HAL UART 框架初体验
  6. 顺通机器人_青白江机器人检测
  7. idea项目中两个模块互相引用互相依赖可能会出现的问题以及解决方法
  8. php去掉首尾第一个字符,php怎样去除首尾字符
  9. 哈哈日语 日语学习基础入门----五十音(二)
  10. Python学习笔记——《吴恩达Machine Learning》线性回归例程