【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 ...
随机推荐
- Java向指定Excel写入读取数据
今天在开发中遇到用户列表导入导出的功能实现,这里了解到使用POI函数库可以完成此任务!特此记录一下 POI Apache POI是Apache软件基金会开放的源码函数库,POI提供API给Java程序 ...
- 【Java集合】HashSet源码解析以及HashSet与HashMap的区别
HashSet 前言 HashSet是一个不可重复且元素无序的集合.内部使用HashMap实现. 我们可以从HashSet源码的类注释中获取到如下信息: 底层基于HashMap实现,所以迭代过程中不能 ...
- 天梯赛练习 L3-011 直捣黄龙 (30分) dijkstra + dfs
题目分析: 本题我有两种思路,一种是只依靠dijkstra算法,在dijkstra部分直接判断所有的情况,以局部最优解得到全局最优解,另一种是dijkstra + dfs,先计算出最短距离以及每个点的 ...
- Python基础语法2-数据类型
一,数字. 2. 字符串类型 3.列表 4.元组 5.集合 6.字典 7.数据类型转换: 8.序列操作
- 一道有趣的golang排错题
很久没写博客了,不得不说go语言爱好者周刊是个宝贝,本来想随便看看打发时间的,没想到一下子给了我久违的灵感. go语言爱好者周刊78期出了一道非常有意思的题目. 我们来看看题目.先给出如下的代码: p ...
- IDEA 常用的一些 (就几个) 快捷键
快捷键 说明 Ctrl + P 提示类参数 Ctrl + Q 提示类的属性和方法包名 Ctrl + D 复制一行到下一行 Ctrl + F 查找 Ctrl + R 替换 Ctrl + Z 撤销 Ctr ...
- CVE-2020-0796复现
今天整理资料时发现了之前存的一个cve漏洞复现过程,当时打算跟着复现来着,后来也没去复现,今天刚好有时间,所以来复现一下这个漏洞 漏洞讲解 https://www.freebuf.com/vuls/2 ...
- mysql—make_set函数
使用格式:MAKE_SET(bits,str1,str2,-) 1 返回一个设定值(含子字符串分隔字符串","字符),在设置位的相应位的字符串.str1对应于位0,str2到第1位 ...
- 三十三:WEB漏洞-逻辑越权之水平垂直越权
水平和垂直越权 水平越权:可以获得同级别用户权限 垂直权限:享受高几个层次的用户权限 解释,原理,检测,利用,防御 通过更换的某个ID之类的身份标识,从而使得A账号获取(修改,删除)B账号的数据,通过 ...
- 处理 K8S Orphaned pod found - but volume paths are still present on disk 孤儿pod
问题概述 查看kubelet或/var/log/messages日志一直包错,发现是孤儿pod,是由于其pod被删除后存储路径还保存在磁盘. 报错如下 [root@node5 ~]# journalc ...