最长上升(不下降)子序列(LIS) 不同求解方法(动规、贪心)
给定一个序列,求出它的最长上升子序列或者是最长不下降子序列的长度 或者输出这个子序列
一、动态规划 O(n^2)
1.求长度
首先来讨论最长上升子序列的情况,即子序列是严格上升的
假如我们以dp[i]表示以a[i]为结尾的上升子序列的长度 那么对于 j (1<=j<i),如果a[j]<a[i],很显然:
代码:
#include <bits/stdc++.h> using namespace std; int anss=,i,n,j,a[],dp[]; int main()
{
cin>>n;
for(i=;i<n;i++)
{
cin>>a[i];
}
for(i=;i<n;i++)
{
dp[i]=;
for(j=;j<i;j++)
{
if(a[j]<a[i]) //如果是最长不下降子序列就改为 if(a[j]<=a[i])
{
dp[i]=max(dp[j]+,dp[i]);
}
}
if(dp[i]>anss)
anss=dp[i];
}
cout<<anss<<endl;
}
2.求序列
只需要从dp数组向前遍历,找到dp[i]==anss的之后再找dp[i]==anss-1的....以此类推即可
#include <bits/stdc++.h> using namespace std; int anss=,i,n,j,a[],dp[]; int main()
{
cin>>n;
for(i=;i<n;i++)
{
cin>>a[i];
}
for(i=;i<n;i++)
{
dp[i]=;
for(j=;j<i;j++)
{
if(a[j]<a[i])
{
dp[i]=max(dp[j]+,dp[i]);
}
}
if(dp[i]>anss)
anss=dp[i];
}
cout<<anss<<endl;
}
不过通常最长上升子序列的解是不唯一的,长度是唯一的。
二、贪心 O(nlogn)
对于一个上升子序列,显然其结尾元素越小,越有利于在后面接其他的元素,也就越可能变得更长。
因此,我们只需要维护 dp 数组(虽然已经不是动态规划了),对于每一个a [ i ],如果a [ i ]能接到 LIS 后面,就接上去;否则,就用 a [ i ] 取更新 dp数组:在dp数组中找到第一个大于等于a [ i ]的元素dp[ j ],用a [ i ]去更新dp [ j ]。怎么找到第一个大于等于的元素呢?只需要使用lower_bound()函数即可。
至于最长不下降子序列,只需要将 “在dp数组中找到第一个大于等于a [ i ]的元素dp[ j ]” 这一步改为找到第一个大于的元素即可。同样的将lower_bound换成upper_bound()
1.代码
#include <bits/stdc++.h> using namespace std; int anss=,i,n,j,a[],dp[],temp; int main()
{
cin>>n;
for(i=;i<n;i++)
{
cin>>a[i];
dp[i]=0x7ffffff;
}
for(i=;i<n;i++)
{
temp=lower_bound(dp,dp+n,a[i])-dp;
if(temp+>anss)
{
anss++;
}
dp[temp]=a[i];
}
cout<<anss<<endl;
}
2.求序列
只需要另外开一个数组b,记录dp[i]的位置,然后从b数组向前遍历,找到b[i]==anss的之后再找b[i]==anss-1的....以此类推
#include <bits/stdc++.h> using namespace std; int anss=,i,n,j,a[],dp[],temp,b[],c[]; int main()
{
cin>>n;
for(i=;i<n;i++)
{
cin>>a[i];
dp[i]=0x7ffffff;
}
for(i=;i<n;i++)
{
temp=lower_bound(dp,dp+n,a[i])-dp;
if(temp+>anss)
{
anss++;
}
dp[temp]=a[i];
b[i]=temp;
}
cout<<anss<<endl;
temp=anss-;
for(i=n-;i>=;i--)
{
if(b[i]==temp)
{
c[temp]=a[i];
temp--;
}
}
for(i=;i<anss;i++)
{
cout<<c[i]<<' ';
}
}
最长上升(不下降)子序列(LIS) 不同求解方法(动规、贪心)的更多相关文章
- 最长非降/下降子序列问题(DP)(待续...)
注意:抽象成以下描述即为最长非降/下降子序列问题(一维状态) 问题描述:在一个无序的序列a1,a2,a3,a4…an里,找到一个最长的序列满足:(不要求连续) ai<=aj<=ak…< ...
- Luogu 1020 导弹拦截(动态规划,最长不下降子序列,二分,STL运用,贪心,单调队列)
Luogu 1020 导弹拦截(动态规划,最长不下降子序列,二分,STL运用,贪心,单调队列) Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺 ...
- 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 ...
- hdu 4604 Deque(最长上升与下降子序列-能够重复)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4604 这个题解有点问题,暂时没时间改,还是参考别人的吧 #include <cstdio> ...
- 求最长非降(递增)子序列LIS的长度,及注意事项
非降序列(Increasing Sequence)例如: (1) 完全递增型序列:S={1,3,6,7,9} (2) 部分存在等于的序列:S={1,3,3,6,9} S的非降子序列:由原序列S的元素组 ...
- Longest Ordered Subsequence POJ - 2533 dp 最长上升/不下降 子序列
#include<iostream> using namespace std ; ; int f[N]; int a[N]; int n; int main() { cin>> ...
- 动态规划——最长不下降子序列(LIS)
最长不降子序列是这样一个问题: 下面介绍动态规划的做法. 令 dp[i] 表示以 A[i] 结尾的最长不下降序列长度.这样对 A[i] 来说就会有两种可能: 如果存在 A[i] 之前的元素 A[j] ...
- HDU 6357.Hills And Valleys-字符串非严格递增子序列(LIS最长非下降子序列)+动态规划(区间翻转l,r找最长非递减子序列),好题哇 (2018 Multi-University Training Contest 5 1008)
6357. Hills And Valleys 自己感觉这是个好题,应该是经典题目,所以半路选手补了这道字符串的动态规划题目. 题意就是给你一个串,翻转任意区间一次,求最长的非下降子序列. 一看题面写 ...
随机推荐
- 手动编译源码安装包报错 fatal error:cruses.h: no such file or direcrory
很明显是缺少cruses.h这个文件,但是用yum搜索又搜不到,可能是我的yum源的库包太少的原因吧. 后来多方查找,发现cruses.h这个头文件属于ncurses模块,需要安装ncurses-de ...
- Harbor ($docker login) Error saving credentials
$ sudo apt-get install $ sudo apt-get install gnupg2 pass 问题解决!
- HTTP 请求出现 405 not allowed 的一种解决办法
问题:http post请求网页会出现405 原因: Apache.IIS.Nginx等绝大多数web服务器,都不允许静态文件响应POST请求 解决:将post请求改为get请求
- Qt:路径问题小结
在做Qt项目的时候,我们难免遇到到文件路径问题. 如QFile file("text.txt")加载不成功.QPixmap("../text.png") 加载图 ...
- CSS currentColor 变量
㈠currentColor定义及理解 来自MDN的解释:currentColor代表了当前元素被应用上的color颜色值. 使用它可以将当前这个颜色值应用到其他属性上,或者嵌套元素的其他属性上. 你这 ...
- 转载:tcp详解
TCP详解 转自:http://www.cnblogs.com/kzloser/articles/2582957.html 首部格式 图释: 各个段位说明: 源端口和目的端口: 各占 2 字节.端口是 ...
- Spring Boot教程(三十二)多数据源配置与使用(1)
之前在介绍使用JdbcTemplate和Spring-data-jpa时,都使用了单数据源.在单数据源的情况下,Spring Boot的配置非常简单,只需要在application.propertie ...
- MySQ彻底删除与安装配置
彻底删除 1.查看 MySQL 安装了哪些东西 rpm -qa |grep -i mysql 2.卸载 -.el7.x86_64 -.el7.x86_64 .noarch -.el7.x86_64 - ...
- C++入门经典-例6.12-使用数组地址将二维数组输出
1:以a[4][3]为例 a代表二维数组的地址,通过指针运算符可以获取数组中的元素 (1)a+n代表第n行的首地址 (2)&a[0][0]既可以看作第0行0列的首地址,同样也可以被看作是二维数 ...
- spring的AOP基本原理
一.什么是AOP AOP(Aspect Oriented Programming),意思是面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP基于IoC基础,是对OOP ...