LIS (最长上升子序列)

LIS两种写法

O(n^2)

dp[i]表示以a[i]结尾的为LIS长度

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <cstdio>
 6 #include <vector>
 7 #include <cmath>
 8 #include <ctime>
 9 #include <list>
10 #include <set>
11 #include <map>
12 using namespace std;
13 typedef long long LL;
14 typedef pair <int, int> P;
15 const int N = 2e3 + 5;
16 int dp[N];
17 int a[N];
18
19 int main()
20 {
21     int n;
22     while(~scanf("%d", &n)) {
23         memset(dp, 0, sizeof(dp));
24         int res = 0;
25         for(int i = 1; i <= n; ++i) {
26             scanf("%d", a + i);
27             dp[i] = 1;
28             for(int j = 1; j < i; ++j) {
29                 if(a[i] > a[j])
30                     dp[i] = max(dp[i], dp[j] + 1);
31             }
32             res = max(res, dp[i]);
33         }
34         printf("%d\n", res);
35     }
36     return 0;
37 }

O(nlogn)

dp[i]表示LIS长度为i的最后一个元素

 1 //#pragma comment(linker, "/STACK:102400000, 102400000")
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <cstdlib>
 5 #include <cstring>
 6 #include <cstdio>
 7 #include <vector>
 8 #include <cmath>
 9 #include <ctime>
10 #include <list>
11 #include <set>
12 #include <map>
13 using namespace std;
14 typedef long long LL;
15 typedef pair <int, int> P;
16 const int N = 1e5 + 5;
17 int dp[N], a[N], inf = 1e6;
18
19 int main()
20 {
21     int n;
22     while(~scanf("%d", &n)) {
23         for(int i = 0; i <= n + 1; ++i)
24             dp[i] = inf;
25         for(int i = 1; i <= n; ++i) {
26             scanf("%d", a + i);
27             *lower_bound(dp, dp + n, a[i]) = a[i];
28         }
29         printf("%d\n", lower_bound(dp, dp + n, inf) - dp);
30     }
31     return 0;
32 }

时间: 2024-10-12 13:29:11

LIS (最长上升子序列)的相关文章

hdu 5256 序列变换(LIS最长上升子序列)

Problem Description 我们有一个数列A1,A2...An,你现在要求修改数量最少的元素,使得这个数列严格递增.其中无论是修改前还是修改后,每个元素都必须是整数. 请输出最少需要修改多少个元素. Input 第一行输入一个T(1≤T≤10),表示有多少组数据 每一组数据: 第一行输入一个N(1≤N≤105),表示数列的长度 第二行输入N个数A1,A2,...,An. 每一个数列中的元素都是正整数而且不超过106. Output 对于每组数据,先输出一行 Case #i: 然后输出

POJ 1887 Testingthe CATCHER (LIS:最长下降子序列)

POJ 1887Testingthe CATCHER (LIS:最长下降子序列) http://poj.org/problem?id=3903 题意: 给你一个长度为n (n<=200000) 的数字序列, 要你求该序列中的最长(严格)下降子序列的长度. 分析:        读取全部输入, 将原始数组逆向, 然后求最长严格上升子序列就可以. 因为n的规模达到20W, 所以仅仅能用O(nlogn)的算法求.        令g[i]==x表示当前遍历到的长度为i的全部最长上升子序列中的最小序列末

POJ - 3903 Stock Exchange(LIS最长上升子序列问题)

E - LIS Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Description The world financial crisis is quite a subject. Some people are more relaxed while others are quite anxious. John is one of them. He is very concerned abo

lis(最长上升子序列) dp

lis(最长上升子序列) dp 求序列的lis,子序列可不连续 for(int i=1;i<=N;i++){ scanf("%d",&a[i]); dp[i]=1; } for(int i=2;i<=N;i++){ for(int j=1;j<i;j++){ if(a[j]<a[i]) dp[i]=max(dp[i],dp[j]+1); } } int ans=1; for(int i=1;i<=N;i++){ //注意并不是dp[N]最大,而是要

poj2533——lis(最长上升子序列), 线性dp

poj2533——lis(最长上升子序列), 线性dp Longest Ordered Subsequence Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 36143   Accepted: 15876 Description A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequence of the given n

hdu 5421 小明系列问题——小明序列(LIS最长上升子序列)

1 /***************************************************** 2 题目: 小明系列问题——小明序列(hdu 4521) 3 链接: http://acm.hdu.edu.cn/showproblem.php?pid=4521 4 算法: LIS最长上升子序列 5 6 ******************************************************/ 7 #include<cstdio> 8 #include<

POJ 3903 Stock Exchange (LIS:最长上升子序列)

POJ 3903Stock Exchange (LIS:最长上升子序列) http://poj.org/problem?id=3903 题意: 给你一个长度为n (n<=100000) 的数字序列, 要你求该序列中的最长(严格)上升子序列的长度. 分析: 由于n的规模达到10W, 所以只能用O(nlogn)的算法求. 令g[i]==x表示当前遍历到的长度为i的所有最长上升子序列中的最小序列末尾值为x.(如果到目前为止, 根本不存在长i的上升序列, 那么x==INF无穷大) 假设当前遍历到了第j个

算法设计 - LCS 最长公共子序列&amp;&amp;最长公共子串 &amp;&amp;LIS 最长递增子序列

出处 http://segmentfault.com/blog/exploring/ 本章讲解:1. LCS(最长公共子序列)O(n^2)的时间复杂度,O(n^2)的空间复杂度:2. 与之类似但不同的最长公共子串方法.最长公共子串用动态规划可实现O(n^2)的时间复杂度,O(n^2)的空间复杂度:还可以进一步优化,用后缀数组的方法优化成线性时间O(nlogn):空间也可以用其他方法优化成线性.3.LIS(最长递增序列)DP方法可实现O(n^2)的时间复杂度,进一步优化最佳可达到O(nlogn)

动态规划模板1|LIS最长上升子序列

LIS最长上升子序列 dp[i]保存的是当前到下标为止的最长上升子序列的长度. 模板代码: int dp[MAX_N], a[MAX_N], n; int ans = 0; // 保存最大值 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(ans, dp[i]); }

LIS 最长递增子序列问题

一,    最长递增子序列问题的描述 设L=<a1,a2,…,an>是n个不同的实数的序列,L的递增子序列是这样一个子序列Lin=<aK1,ak2,…,akm>,其中k1<k2<…<km且aK1<ak2<…<akm.求最大的m值. 比如int* inp = {9,4,3,2,5,4,3,2}的最长递减子序列为{9,5,4,3,2}: 二,解决: 1.用一个临时数组tmp保存这样一种状态:tmp[i]表示以i为终点的递增序列的长度: 比如inp =