最长不下降子序列(LIS)
最长上升子序列、最长不下降子序列,解法差不多,就一点等于不等于的差别,我这里说最长不下降子序列的。
有两种解法。
一种是DP,很容易想到,就这样:
REP(i,n)
{
f[i]=;
FOR(j,,i-)
if(a[j]<=a[i]) f[i]=max(f[i],f[j]+);
}
DP是O(n^2)的,我感觉已经不错了不过还有超碉的nlogn的方法。
nlogn的方法:
用栈和二分查找。
遇到一个元素a[i],若它不小于栈顶s[top],直接入栈;若小于栈顶,则在栈中二分查找,用它替换栈中比它大的第一个元素。最终栈的大小就是最长不下降子序列的长度(栈中元素并不一定是这个子序列,只有大小是一样的)
例题:http://acm.hdu.edu.cn/showproblem.php?pid=1950
DP代码(例题TLE):
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
using namespace std;
#define ll __int64
#define usint unsigned int
#define mz(array) memset(array, 0, sizeof(array))
#define minf(array) memset(array, inf, sizeof(array))
#define REP(i,n) for(int i=0;i<(n);i++)
#define FOR(i,x,n) for(int i=(x);i<=(n);i++)
#define RD(x) scanf("%d",&x)
#define WN(x) printf("%d\n",x);
#define RE freopen("D.in","r",stdin)
#define WE freopen("1.out","w",stdout) const int maxn=; int a[maxn];
int f[maxn];
int main()
{
//RE;
int t,n,i,j;
int ans;
RD(t);
while(t--)
{
RD(n);
ans=;
REP(i,n)
RD(a[i]);
REP(i,n)
{
f[i]=;
FOR(j,,i-)
if(a[j]<=a[i]) f[i]=max(f[i],f[j]+);
if(f[i]>ans)ans=f[i];
}
WN(ans);
}
return ;
}
nlogn代码:
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<stack>
using namespace std;
#define ll __int64
#define usint unsigned int
#define mz(array) memset(array, 0, sizeof(array))
#define minf(array) memset(array, inf, sizeof(array))
#define REP(i,n) for(int i=0;i<(n);i++)
#define FOR(i,x,n) for(int i=(x);i<=(n);i++)
#define RD(x) scanf("%d",&x)
#define WN(x) printf("%d\n",x);
#define RE freopen("D.in","r",stdin)
#define WE freopen("1.out","w",stdout) const int maxn=; int a[maxn];
int s[maxn],sn;
int main() {
//RE;
int t,n,i,j;
int l,r,mid;
int ans;
RD(t);
while(t--) {
RD(n);
ans=;
REP(i,n)
RD(a[i]);
sn=;
s[]=a[];
FOR(i,,n-) {
if(s[sn-]<=a[i]) s[sn++]=a[i];
else {
l=;
r=sn-;///二分找比a[i]大的第一个(s[sn-1]肯定比a[i]大,l不会加爆)
while(l<=r) {
mid=(l+r)>>;
if(s[mid]>a[i]) r=mid-;
else l=mid+;
}
s[l]=a[i];
}
}
WN(sn);
}
return ;
}
最长不下降子序列(LIS)的更多相关文章
- SPOJ 3943 - Nested Dolls 最长不下降子序列LIS(二分写法)
现在n(<=20000)个俄罗斯套娃,每个都有宽度wi和高度hi(均小于10000),要求w1<w2并且h1<h2的时候才可以合并,问最少能剩几个. [LIS]乍一看跟[这题]类似, ...
- HDU 1087 最长不下降子序列 LIS DP
Nowadays, a kind of chess game called “Super Jumping! Jumping! Jumping!” is very popular in HDU. May ...
- [Swust OJ 585]--倒金字塔(LIS最长不下降子序列)
题目链接:http://acm.swust.edu.cn/problem/585/ Time limit(ms): 3000 Memory limit(kb): 65535 SWUST国的一支科学 ...
- 动态规划——最长不下降子序列(LIS)
最长不降子序列是这样一个问题: 下面介绍动态规划的做法. 令 dp[i] 表示以 A[i] 结尾的最长不下降序列长度.这样对 A[i] 来说就会有两种可能: 如果存在 A[i] 之前的元素 A[j] ...
- 动态规划 ---- 最长不下降子序列(Longest Increasing Sequence, LIS)
分析: 完整 代码: // 最长不下降子序列 #include <stdio.h> #include <algorithm> using namespace std; ; in ...
- 算法进阶 (LIS变形) 固定长度截取求最长不下降子序列【动态规划】【树状数组】
先学习下LIS最长上升子序列 看了大佬的文章OTZ:最长上升子序列 (LIS) 详解+例题模板 (全),其中包含普通O(n)算法*和以LIS长度及末尾元素成立数组的普通O(nlogn)算法,当然还 ...
- HDU 6357.Hills And Valleys-字符串非严格递增子序列(LIS最长非下降子序列)+动态规划(区间翻转l,r找最长非递减子序列),好题哇 (2018 Multi-University Training Contest 5 1008)
6357. Hills And Valleys 自己感觉这是个好题,应该是经典题目,所以半路选手补了这道字符串的动态规划题目. 题意就是给你一个串,翻转任意区间一次,求最长的非下降子序列. 一看题面写 ...
- 最长不下降子序列的O(n^2)算法和O(nlogn)算法
一.简单的O(n^2)的算法 很容易想到用动态规划做.设lis[]用于保存第1~i元素元素中最长不下降序列的长度,则lis[i]=max(lis[j])+1,且num[i]>num[j],i&g ...
- hdu 4604 Deque(最长不下降子序列)
从后向前对已搜点做两遍LIS(最长不下降子序列),分别求出已搜点的最长递增.递减子序列长度.这样一直搜到第一个点,就得到了整个序列的最长递增.递减子序列的长度,即最长递减子序列在前,最长递增子序列在后 ...
随机推荐
- Java系列:国际化(zz)
国际化英文单词为:Internationalization,又称I18N,I为因为单词的第一个字母,18为这个单词的长度,而N代表这个单词的最后一个字母.国际化又称本地化(Localization,L ...
- EF实体框架之CodeFirst八
前面七篇基本把Code First学习了一下,不过code first中会出现一个问题,就是数据迁移的问题. 一.数据准备 还是在前面的demo上修改,这次使用Province和City类. publ ...
- El Capitan 中 SIP 介绍
http://havee.me/mac/2015-10/system-integrity-protection-on-el-capitan.html 这两天大家纷纷将 OS X 系统升级到了 El C ...
- 自己写了个H5版本的俄罗斯方块
在实习公司做完项目后,实在无聊.就用H5写了几个游戏出来玩一下.从简单的做起,就搞了个经典的俄罗斯方块游戏. 先上效果: 上面的数字是得分,游戏没有考虑兼容性,只在chrome上测试过,不过大部分现代 ...
- ModernUI教程:使用预定义的页面布局
Modern UI for WPF自带了一组页面布局.Modern UI page是继承自control控件的,Page通过是通过ModernWindow.MenuLinkGroups属性来引用显示在 ...
- SQL温故系列两篇(一)
1.不允许保存更改.您所做的更改要求删除并重新创建以下表 关于SQL2008 “不允许保存更改.您所做的更改要求删除并重新创建以下表. 打开SQL SERVER 2008 工具-->选项--&g ...
- DateTime类常用技巧摘录
//今天 DateTime.Now.Date.ToShortDateString(); //昨天,就是今天的日期减一 DateTime.Now.AddDays(-).ToShortDateString ...
- [工具类]获取url中参数列表
写在前面 在项目中经常用到解析url中参数的逻辑,今天先下载就自己封装了一个方法,方便以后使用的时候,信手拈来.当然这里给出的方法是针对常见的url参数类型的,对于重写url,或者路由格式的不考虑. ...
- GIthub的小技巧
目录: 一.快捷键一览表 二.快速搜索项目文件功能 三.使用Github Pages搭建项目网站 一.快捷键一览表 具体操作: 在各个页面下按下shift+/也就是?都可以打开键盘快捷 ...
- WPF小知识,MessageBox的多种用法
我们在程序中经常会用到MessageBox. 现将其常见用法总结如下: 1.MessageBox.Show("Hello~~~~"); 最简单的,只显示提示信息. 2.Messag ...