最长上升(不下降)子序列(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 自己感觉这是个好题,应该是经典题目,所以半路选手补了这道字符串的动态规划题目. 题意就是给你一个串,翻转任意区间一次,求最长的非下降子序列. 一看题面写 ...
随机推荐
- sizeof运算符、字节对齐考点(面宝P50)
记住几句话: 结构体的长度一定是最长的数据元素类型的整数倍: 某数据元素的起始地址能被该类型所占的字节数整除: 静态变量是存放在全局数据区,而sizeof计算栈中分配的大小,不包括static变量: ...
- Python CGI编程Ⅵ
GET和POST方法 浏览器客户端通过两种方法向服务器传递信息,这两种方法就是 GET 方法和 POST 方法. 使用GET方法传输数据 GET方法发送编码后的用户信息到服务端,数据信息包含在请求页面 ...
- wx小程序知识点(七)
七.小程序提速与性能优化 参考大佬vicyao的文章 https://blog.csdn.net/wetest_tencent/article/details/61196522 (1)提高页面加载速度 ...
- ASP.NET通过反射生成sql语句
最近对接一个接口,需要通过xml序列化成实体后添加额外信息后批量插入数据库,需要手动拼sql.因为涉及多张表,拼凑很麻烦而且容易出错,所以写了两个工具方法来生成sql,先写到博客里面,以便以后不时之需 ...
- hive on tez 任务失败
最近再hue 集群查询任务经常失败,经过几天的观察,终于找到原因,报错如下 Status: FailedVertex failed, vertexName=Map 1, vertexId=vertex ...
- pip & conda 换源
conda换源方法具体参考清华大学镜像站Anaconda 镜像使用帮助 conda config --add channels https://mirrors.tuna.tsinghua.edu.cn ...
- C++入门经典-例3.14-使用while循环计算从1到10的累加
1:代码如下: // 3.14.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> usin ...
- 界面之下:还原真实的 MV* 模式
界面之下:还原真实的MV*模式 作者:戴嘉华 转载请注明出处并保留原文链接( https://github.com/livoras/blog/issues/11 )和作者信息. 目录: 前言 MVC ...
- /usr/bin/env python no such file or directory: dos格式导致的!
最近修改了几个python文件,发现在linux上只能用python file来执行,直接./file提示错误"no such file or directory",而脚本是用&q ...
- 四、日志输出Reporter.log
一.Reporter.log import org.testng.Reporter; public class TestLog { public static void main(String[] a ...