首先,让我来看看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;elsel=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求解(包括优化)相关推荐

  1. 对比 GA 、PSO 、DE三种算法 求解连续优化问题的性能

    摘要: 演化计算又称为进化算法.进化计算,是一种元启发式方法.搜索过程是从一个初始解的集合(称为初始种群)开始的,种群中的每一个解都沿着一定的轨迹搜索,每前进一步称为种群的进化,得到的解集称为种群的一 ...

  2. 遗传算法求解函数优化及TSP问题

    本文的pdf文件:link        遗传算法是群智能算法中的一个分支,是一类基于种群搜索的优化算法,受自然界生物进化机制的启发,通过自然选择.变异.重组等操作,针对特定的问题取寻找出一个满意的解 ...

  3. 求解稀疏优化问题——增广拉格朗日方法+半光滑牛顿法

    ↑↑↑↑↑点击上方蓝色字关注我们! 『视学算法』转载 作者:邓康康 邓康康,福州大学应用数学系在读博士生,研究方向:运筹优化算法设计与应用.流形优化. 编者按 本文介绍了一种二阶方法去求解稀疏优化问题 ...

  4. Algorithm:数学建模大赛之数学建模基础(经验/技巧)、流程(模型准备/模型假设/建模/求解/分析/优化/预测/评价)、论文写作(意义/摘要/关键词/问题重述和模型假设/建模/文献)之详细攻略

    Algorithm:数学建模大赛之数学建模基础(经验/技巧).流程(模型准备/模型假设/建模/求解/分析/优化/预测/评价).论文写作(意义/摘要/关键词/问题重述和模型假设/建模/求解/结论/参考文 ...

  5. 割线法求解过程_求解稀疏优化问题2——临近点方法+半光滑牛顿法

    这篇文章是我之前一篇文章的兄弟篇,没看过的可以看下面这个. 邓康康:求解稀疏优化问题--半光滑牛顿方法​zhuanlan.zhihu.com 我们考虑的问题仍然是如下的一般问题: 其中 ,并且 特别大 ...

  6. 求解高维优化问题的改进正弦余弦算法

    文章目录 一.理论基础 1.正弦余弦算法 2.改进的正弦余弦算法 (1)反向学习初始化 (2)修改个体位置更新方程 (3)算法步骤 二.仿真实验与结果分析 1.测试函数 2.实验结果 (1)和原始SC ...

  7. Algorithm:数学建模大赛(CUMCM/NPMCM)之数学建模(经验/技巧)、流程(模型准备/模型假设/建模/求解/分析/优化/预测/评价)、论文写作(意义/摘要/关键词/问题重述和模型假设/建

    Algorithm:数学建模大赛(CUMCM/NPMCM)之数学建模(经验/技巧).流程(模型准备/模型假设/建模/求解/分析/优化/预测/评价).论文写作(意义/摘要/关键词/问题重述和模型假设/建 ...

  8. 【指派问题】基于matlab遗传算法求解指派优化问题【含Matlab源码 2292期】

    ⛄一.遗传算法求解指派优化问题简介 1 遗传算法 1.1 遗传算法简介 遗传算法是模拟生物在自然环境中的遗传和进化过程而形成的一种自适应全局优化概率搜索算法,它是一种多学科融合交叉的产物.遗传算法通过 ...

  9. ABC人工蜂群算法求解函数优化实例C++(2020.11.5)

    ABC人工蜂群算法C++ 人工蜂群算法 1.原理 2.算法流程 3.函数优化实例 4.求解函数优化的ABC源代码C++ 人工蜂群算法 1.原理 最常见的基于蜜蜂采蜜行为的蜂群算法是Karaboga(2 ...

  10. Tabu搜索(TS—Tabu search)算法是近年来出现的用于求解组合优化问题的一种高效的启发式搜索技术。 本文采用固定并联电容器作为研究对象对系统进行无功补偿,并利用智能优化方法得到使配电网损耗

    禁忌搜索算法解决配电网无功优化问题对应的MATLAB源码,有对应的参考资料. 电力系统配电网的无功优化规划是保证配电网安全.经济运行的一项有效手段,是降低网损.提高电压质量的重要措施. 因此,电力系统 ...

最新文章

  1. 韦布望远镜现在到哪儿了:距离地球60万公里,NASA还说可以用10年
  2. do while循环猜电脑给出的随机数
  3. oracle 读取表结构和注释,生成数据库结构文档
  4. 如何批量在文件夹中建立php,怎么批量创建文件夹_一次性创建多个文件夹方法_一聚教程网...
  5. SQLSERVER之快速掌握T-SQL语句
  6. ESX的VSWITCH坏了,如何转移到新建的虚拟交换机上?
  7. 网易云音乐UC!缓存格式文件转MP3方法
  8. 频率泄露以及加窗原理
  9. 无线局域网安全协议(WEP、WPA、WAPI)
  10. 桌面计算机主流硬盘接口,M.2和U.2谁更好?主流硬盘接口大扫盲
  11. 群晖linux怎么进入u盘,超级简单,群晖系统的U盘制作和安装指导,实现家庭云...
  12. 两个月的一些工作总结
  13. [转]UserData使用总结 - lanyu
  14. 数学建模实战9(聚类分析)
  15. 计算机显示屏显示超出屏幕大小,如果计算机提示显示器显示超出范围,该怎么办?...
  16. Selenium浏览器自动化测试工具
  17. 2021杭州·云栖大会来了!门票免费预约
  18. 我们可以从挑战者灾难中学到什么关于网络安全的知识?一切。
  19. 唐代韩愈的《祭十二郎文》
  20. iTunes connect Testflight 2017-04-20改版后的内部测试执行流程

热门文章

  1. 蓝牙耳机品牌哪个好?好用的无线蓝牙耳机推荐
  2. 微信小程序 分享登录的问题
  3. 容易读错的常见常用字
  4. 神州电脑忘记密码怎么搞
  5. python定义向量_python中向量怎么表示
  6. 【C++初阶7-string实现】xxx坐享其成,xxx苦不堪言
  7. Clickhouse批量插入数据时报错:Too many partitions for single INSERT block
  8. HBase 统计表中数据量
  9. c语言判断元旦是星期几,计算任何一天是星期几的C语言源代码.
  10. 文科女生与IT(一)