LIS求解(包括优化)
首先,让我来看看LIS问题
Description
一个数的序列 bi,当 b1 < b2 < ... < bS 的时候,我们称这个序列是上升的。对于给定的一个序列(a1,a2,...,aN),我们可以得到一些上升的子序列(ai1,ai2,...,aiK),这里 1 ≤ i1 < i2 <...< iK ≤ N。比如,对于序列(1,7,3,5,9,4,8),有它的一些上升子序列,如(1,7),(3,4,8)等等。
这些子序列中最长的长度是 4,比如子序列(1,3,5,8)。
你的任务,就是对于给定的序列,求出最长上升子序列的长度。
Format
Input
输入的第一行是序列的长度 N(1 ≤ N ≤ 1000)。
第二行给出序列中的 N 个整数,这些整数的取值范围都在 0 到 10000。
Output
最长上升子序列的长度。
Samples
输入数据 1
7
1 7 3 5 9 4 8
Copy
输出数据 1
4
基础方法求解:
当我们求1~n的LIS长度时,我们可以轻松的发现可以从以前的状态转移过来
- 经典的动态规划问题!!
- 于是我们开始设置状态
- 我们设
表示从以
结尾的最长子序列长度
- 注意初始化:
- 时间复杂度是
Code:
#include<bits/stdc++.h>
using namespace std;
int n,a[10005],dp[10005],ans;
int main(){
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;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(dp[i],ans);
}
cout<<ans;
return 0;
}
优化
- 当
甚至更大,
复杂度的代码肯定会超时
考虑优化?
- 我们注意到,第二层枚举的时候,会枚举很多无用的状态
- 比如:当我们枚举到
时,
完全没有必要枚举,所以我们可以考虑优化
- 我们使用贪心策略:当我们枚举的
更小的时候,就更有可能和
形成更长的子序列
- 因此,我们可以单调维护前面
所有可以考虑转移的数字!
二分(话说什么奇奇怪怪的优化都是他)
- 新建一个
数组,
表示最长上升子序列长度为
的时候最大值
- 我们保证
数组存的是最大值的最小值
- 比如有两个序列
,
- 最长子序列长度是3,但是
存的是5(保证最小)
- 如何维护这个数组呢?
- 两种情况
- 当
>
[当前最长LIS长度],我们就更新最长长度,把a[i]接到后面去
- 当
[当前最长LIS长度]时,我们就更新呗
- 我们注意定义(
表示最长上升子序列长度为
的时候的最小值)
- 我们能做什么?
- 不就是更新最小值吗?
- 又因为
数组是单调递增的(这个应该都知道吧)
- 所以我们二分
数组,找到第一个大于等于
的值,更新即可
- 最后我们输出即可(如果觉得懵的话,可以自己举个例子看看)
- 时间复杂度是:
Code:
#include<bits/stdc++.h>
using namespace std;
int n,m,a[100005],ans[100005],len;
int erfen(int sum){
int l=1,r=len,mid;
while(l<=r){
mid=(l+r)/2;
if(ans[mid]>=sum)
r=mid-1;
else
l=mid+1;
}
return l;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
len=1;
ans[1]=a[1];
for(int i=2;i<=n;i++){
if(a[i]>ans[len])
ans[++len]=a[i];
else{
int pos=erfen(a[i]);
ans[pos]=a[i];
}
}
cout<<len<<endl;
return 0;
}
考虑再次优化?
当有些题目时间卡得非常紧的情况下,二分过大的常数可能导致超时,需要再次优化
我们注意
这条式子,发现我们第二层的任务是找前
的LIS的最长长度
这种修改需要进行单点修改,考虑使用树状数组进行优化
设
表示以i结尾的最长上升子序列长度
我们将原数组从小到大排序,并记录他原来的下标(有点像二分),设他为
数组
我们遍历到
时,找到
~
的最大值,然后对这个值+1进行更新
时间复杂度是:
注意:如果不去重,就会成为最长不下降子序列
Code:
#include<bits/stdc++.h>
using namespace std;
struct node{int value,num;}a[30005];
int n,t[30005],b[30005],maxx;
bool cmp(node x,node y){
return x.value<y.value;
}
int lowbit(int x){
return x&(-x);
}
int ask(int x){//查找t1~tx的最大值
int res=-1e9;
for(;x;x-=lowbit(x))
res=max(res,t[x]);
return res;
}
void modify(int x,int r){//更新这个点的最大值
for(;x<=n;x+=lowbit(x))
t[x]=max(t[x],r);
}
void solve(){
for(int i=1;i<=n;i++){
int x=ask(a[i].num);
modify(a[i].num,++x);
maxx=max(maxx,x);
}
}
int main(){
cin>>n;
for(int i=1;i<=n;i++)
cin>>b[i];
for(int i=1;i<=n;i++)
a[i].value=b[i],a[i].num=i;
sort(a+1,a+1+n,cmp);
solve();
cout<<maxx;
return 0;
}
(如果想了解树状数组,请到我的另一篇博客去咯loolook)
单看着干嘛?还不去写代码????!!!
LIS求解(包括优化)的更多相关文章
- MySQL与MariaDB核心特性比较详细版v1.0(覆盖mysql 8.0/mariadb 10.3,包括优化、功能及维护)
注:本文严禁任何形式的转载,原文使用word编写,为了大家阅读方便,提供pdf版下载. MySQL与MariaDB主要特性比较详细版v1.0(不含HA).pdf 链接:https://pan.baid ...
- D. Babaei and Birthday Cake---cf629D(LIS线段树优化)
题目链接:http://codeforces.com/problemset/problem/629/D 题意就是现有n个蛋糕,蛋糕的形状是圆柱体,每个蛋糕的体积就是圆柱体的体积,每个蛋糕的编号是1-- ...
- spark性能优化(包括优化原理及基本方法)
https://www.jianshu.com/p/b8841a8925fb spark性能优化 1.诊断内存的消耗 2. 高性能序列化类库 3. 优化数据结构 4. 对多次使用的rdd进行持久化或者 ...
- zoj 1008 暴力枚举求解dfs+优化
/* 现将相同的合并计数. 再枚举判断是否符合当cou==n*n是符合就退出 */ #include<stdio.h> #include<string.h> #define N ...
- Luogu-P1020(导弹拦截)(DP,LIS ,二分优化)
Luogu-P1020(导弹拦截)(DP) 题意: 给n(n<=100000) 个数字,求最长不上升子序列的长度和最少的不上升子序列的个数. 分析: 第一问: 求最长不上升子序列有 O(n^2) ...
- SGU 521 North-East ( 二维LIS 线段树优化 )
521. "North-East" Time limit per test: 0.5 second(s)Memory limit: 262144 kilobytes input: ...
- P1020 导弹拦截 /// DP Dilworth定理 LIS、LDS优化
题目大意: https://www.luogu.org/problemnew/show/P1020 Dliworth有两个互相对偶的定理:U的链划分使用的最少集合数,等于它的最大反链长度.(1)U的反 ...
- 【优化算法】遗传算法GA求解混合流水车间调度问题(附C++代码)
00 前言 各位读者大家好,好久没有介绍算法的推文了,感觉愧对了读者们热爱学习的心灵.于是,今天我们带来了一个神奇的优化算法--遗传算法! 它的优点包括但不限于: 遗传算法对所求解的优化问题没有太多的 ...
- 深入理解图优化与g2o:图优化篇
前言 本节我们将深入介绍视觉slam中的主流优化方法——图优化(graph-based optimization).下一节中,介绍一下非常流行的图优化库:g2o. 关于g2o,我13年写过一个文档,然 ...
随机推荐
- Springboot+vue 实现汽车租赁系统(毕业设计二)(前后端项目分离)
文章目录 1.系统功能列表 2.管理员端界面 2.1 商家登录界面 2.2 用户信息管理界面 2.3 汽车管理界面 2.4 订单界面 2.5 汽车图形报表 2.6 优惠券新增界面 3.普通用户界面 3 ...
- 泛化之美 —— C++11 可变参数模板的妙用
概述 首先这篇文章出自博客园作者:[qicosmos ],我对本文的实例代码进行了学习.思考和整理纠正,理清了文章的全部细节,觉得这是一篇让我受益匪浅的文章.之所以会接触「可变参数模板」这部分的内容, ...
- 深度学习环境搭建常用网址、conda/pip命令行整理(pytorch、paddlepaddle等环境搭建)
前言:最近研究深度学习,安装了好多环境,记录一下,方便后续查阅. 1. Anaconda软件安装 1.1 Anaconda Anaconda是一个用于科学计算的Python发行版,支持Linux.Ma ...
- ubuntu下Mysql安装与root密码重置
一.安装 1.首先更新本地存储库索引,执行sudo apt update 2.从APT存储库安装MySQL,执行sudo apt install MySQL-server,在安装过程中,可能会出现[Y ...
- Codeforces Round #781(C. Tree Infection)
Codeforces Round #781 C. Tree Infection time limit per test 1 second memory limit per test 256 megab ...
- Vue3组件间传值
12种方式 1. 父组件 ./father.vue 点击查看代码 <template> <h1>father:</h1> <h3>子组件传过来的:{{ ...
- 阿里云 ACK 接入观测云
简介 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理.2021 年成为国内唯一连续三年入选 Gartner 公共云容器报告的 ...
- bugku 秋名山老司机
看到这个的第一眼怀疑是脚本题,先看看源码 找不到提交点... 抓包 也没有 多刷新几次 弹出了提示信息 用post传入的参数value,其值应该就是计算式的答案 然后直接使用py脚本来快速上传答案值就 ...
- 研究光度立体法阶段性小结和优化(可20ms获取4个2500*2000灰度图的Normal Map)。
这个东西是我接触的第一个非2D方面的算法,到目前为止其实也没有完全搞定,不过可能短时间内也无法突破.先把能搞定的搞定吧. 这个东西也有一大堆参考资料,不过呢,搜来搜去其实也就那些同样的东西,个人觉得就 ...
- WEB入门——信息搜集1-20
WEB1--查看源码 查看源码即可得flag. WEB2--JS前端禁用 查看源码即可得flag. JavaScript实现禁用的方法简单来说就是当用户使用键盘执行某一命令是返回的一种状态,而这种状态 ...