【noi 2.6_1759】LIS 最长上升子序列(DP,3种解法)
题意我就不写了。解法有3种:
1.O(n^2)。2重循环枚举 i 和 j,f[i]表示前 i 位必选 a[i] 的最长上升子序列长度,枚举a[j]为当前 LIS 中的前一个数。
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<iostream>
5 using namespace std;
6
7 const int N=1010;
8 int a[N],f[N];
9
10 int mmax(int x,int y) {return x>y?x:y;}
11 int main()
12 {
13 int n,ans=0;
14 scanf("%d",&n);
15 for (int i=1;i<=n;i++) scanf("%d",&a[i]);
16 for (int i=1;i<=n;i++)
17 {
18 f[i]=1;
19 for (int j=1;j<i;j++)
20 if (a[i]>a[j]) f[i]=mmax(f[i],f[j]+1);
21 ans=mmax(ans,f[i]);
22 }
23 printf("%d",ans);
24 return 0;
25 }
1
2.O(n log n)。继正确但不高效的解法后,我们想要对时间复杂度降维。最常见的做法就是二分查找,这题就是把解法1的 j 的O(n)枚举变为O(log n)的二分。那么二分的范围肯定要包含当前的 LIS 的数,而且要知道这些数对应的 f[ ]值。因此,我们只能保存扫完前 i 个选出的最优的 LIS,上述2个条件都可以满足。同时不断扩大和更新(存尽量小的数)这个序列。
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<iostream>
5 using namespace std;
6
7 const int N=1010;
8 int a[N],f[N];
9
10 int ffind(int l,int r,int x)
11 {
12 if (l==r) return l;
13 int mid=(l+r)>>1;
14 if (x>f[mid]) return ffind(mid+1,r,x);
15 else return ffind(l,mid,x);
16 }
17 int main()
18 {
19 int n,ans=0;
20 scanf("%d",&n);
21 for (int i=1;i<=n;i++) scanf("%d",&a[i]);
22 f[++ans]=a[1];
23 for (int i=2;i<=n;i++)
24 {
25 int x;
26 if (a[i]>f[ans]) x=++ans;
27 else x=ffind(1,ans,a[i]);
28 f[x]=a[i];
29 }
30 printf("%d",ans);
31 return 0;
32 }
2
3.O(n log n)。(参考自蓝书 p62,挖了坑,没时间填了......)
1 for (int i=1;i<=n;i++) g[i]=INF;
2 for (int i=0;i<n;i++)
3 {
4 int k=lower_bound(g+1,g+n+1,A[i])-g;
5 d[i]=k;
6 g[k]=A[i];
7 }
【noi 2.6_1759】LIS 最长上升子序列(DP,3种解法)的更多相关文章
- 动态规划模板1|LIS最长上升子序列
LIS最长上升子序列 dp[i]保存的是当前到下标为止的最长上升子序列的长度. 模板代码: int dp[MAX_N], a[MAX_N], n; int ans = 0; // 保存最大值 for ...
- 算法设计 - LCS 最长公共子序列&&最长公共子串 &&LIS 最长递增子序列
出处 http://segmentfault.com/blog/exploring/ 本章讲解:1. LCS(最长公共子序列)O(n^2)的时间复杂度,O(n^2)的空间复杂度:2. 与之类似但不同的 ...
- POJ - 3903 Stock Exchange(LIS最长上升子序列问题)
E - LIS Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Descripti ...
- hdu 5256 序列变换(LIS最长上升子序列)
Problem Description 我们有一个数列A1,A2...An,你现在要求修改数量最少的元素,使得这个数列严格递增.其中无论是修改前还是修改后,每个元素都必须是整数. 请输出最少需要修改多 ...
- POJ 3903 Stock Exchange (E - LIS 最长上升子序列)
POJ 3903 Stock Exchange (E - LIS 最长上升子序列) 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action ...
- POJ 1887 Testingthe CATCHER (LIS:最长下降子序列)
POJ 1887Testingthe CATCHER (LIS:最长下降子序列) http://poj.org/problem?id=3903 题意: 给你一个长度为n (n<=200000) ...
- LIS最长上升子序列O(n^2)与O(nlogn)的算法
动态规划 最长上升子序列问题(LIS).给定n个整数,按从左到右的顺序选出尽量多的整数,组成一个上升子序列(子序列可以理解为:删除0个或多个数,其他数的顺序不变).例如序列1, 6, 2, 3, 7, ...
- LIS 最长递增子序列
一.最长公共子序列 经典的动态规划问题,大概的陈述如下: 给定两个序列a1,a2,a3,a4,a5,a6......和b1,b2,b3,b4,b5,b6.......,要求这样的序列使得c同时是这两个 ...
- 动态规划——E (LIS())最长上升子序列
E - LIS Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit Stat ...
随机推荐
- 【SpringBoot1.x】SpringBoot1.x 配置
SpringBoot1.x 配置 文章源码 配置文件 SpringBoot 使用一个全局的配置文件,配置文件名是固定的. application.properties.application.yml都 ...
- Flutter 布局类组件:线性布局(Row和Column)
前言 所谓线性布局,即指沿水平或垂直方向排布子组件.Flutter中通过Row和Column来实现线性布局,并且它们都继承自弹性布局(Flex). 接口描述 Row({ Key key, // 表示子 ...
- Shiro的认证与授权
shiro实战教程 一.权限管理 1.1什么是权限管理 基本上涉及到用户参与的系统都需要进行权限管理,权限管理属于系统安全的范畴,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户可以 ...
- python学习笔记 | 猜拳游戏
''' @author: 人人都爱小雀斑 @time: 2020/3/6 18:52 @desc: 实验结果心得: 1.难点主要在判断谁输谁赢 2.挺好的 ''' import random d={1 ...
- 【Linux】fdisk -l发现有加号"+"
今天分区不够了,打算扩下分区,想起当时创建机器的时候还有大约80多个G没有用,今天打算重新利用上 就用了fdisk /dev/sda 创建了两个分区,但是发现分区下面有加号,感到而别的困惑 最后在很多 ...
- random模块常用函数
random模块常用函数: from random import * # Random float: 0.0 <= x < 1.0 random() # Random float: 2.5 ...
- bean与map之间的转化
import java.util.HashMap; import java.util.Map; import org.apache.commons.beanutils.BeanUtils; impor ...
- 2.4V升3.3V,2.4V升3V,1A大电流升压芯片
两节镍氢电池串联就是1.2V+1.2V=2.4V的供电电压了,2.4V升3V, 2.4V升3.3V的话,就能稳压稳定给模块供电了,镍氢电池是会随着使用的电池电量减少的话,电池的电压也是跟着变化的,导致 ...
- MySQL调优性能监控之show profile
用show profile查询工具指定具体的type show profile在mysql5.7之后过时 show profile命令用于跟踪执行过的sql语句的资源消耗信息,可以帮助查看sql语句的 ...
- UT /SIT/ UAT
UT /SIT/ UAT - 云+社区 - 腾讯云 https://cloud.tencent.com/developer/article/1541268 我们公司只有测试环境--准生产环境--生产环 ...