LIS 最长上升序列

  1. #include <iostream>
  2. #include <stdlib.h>
  3. using namespace std;
  4. #define MAX 10000
  5. int num[MAX], n;
  6. /***********************************************************************************************
  7. 经典的O(n^2)的动态规划算法,设num[i]表示序列中的第i个数,
  8. dp[i]表示从1到i这一段中以i结尾的最长上升子序列的长度,初始时设dp[i] = 1(i = 1, 2, ..., len(A))。
  9. 则有动态规划方程:dp[i] = max{1, dp[j] + 1} (j = 1, 2, ..., i - 1, 且num[j] < num[i])。
  10. ***********************************************************************************************/
  11. int dp[MAX]; //save length
  12. int DP()
  13. {
  14. int maxn = 0;
  15. for(int i=0; i<=n; i++)
  16. {
  17. dp[i] = 1;
  18. for(int j=0; j<i; j++)
  19. {
  20. if(num[i]> num[j] && dp[i] < dp[j] + 1)
  21. dp[i] = dp[j] + 1;
  22. }
  23. if(dp[i] > dp[maxn])
  24. maxn = i;
  25. }
  26. return maxn;
  27. }
  28. /********************************************************************************************
  29. 时间复杂度 nlog(n)
  30. 开一个栈,每次取栈顶元素top和读到的元素temp做比较,如果temp > top 则将temp入栈;
  31. 如果temp < top则二分查找栈中的比temp大的第1个数,并用temp替换它。 最长序列长度即为栈的大小top。
  32. 这也是很好理解的,对于x和y,如果x < y且Stack[y] < Stack[x],用Stack[x]替换Stack[y],
  33. 此时的最长序列长度没有改变但序列Q的‘‘潜力‘‘增大了。
  34. 举例:原序列为1,5,8,3,6,7
  35. 栈为1,5,8,此时读到3,用3替换5,得到1,3,8;
  36. 再读6,用6替换8,得到1,3,6;再读7,得到最终栈为1,3,6,7。最长递增子序列为长度4。
  37. **********************************************************************************************/
  38. int Greedy()
  39. {
  40. int stack[MAX];
  41. int top = 0;
  42. int tp;
  43. stack[top] = num[0]; /* 第一个元素可能为0 */
  44. for(int i = 1; i<n; i++)
  45. {
  46. int low = 0, high = top;
  47. int mid;
  48. while(low <= high) /* 二分检索栈中比temp大的第一个数 */
  49. {
  50. mid = (low + high)/2;
  51. if(stack[mid] > num[i])
  52. low = mid + 1;
  53. else high = mid - 1;
  54. }
  55. if(low == top + 1) top++;
  56. stack[low] = num[i];
  57. }
  58. return top + 1;
  59. /* 最长序列数就是栈的大小(top+1) 最长上升序列存在stack中*/
  60. }

来自为知笔记(Wiz)

附件列表

时间: 2024-08-29 04:07:37

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

数据结构与算法学习之路:LIS——最长递增序列的动态规划算法和二分思想算法

一.最长递增序列的问题描述: 求一个整数序列的最长递增子序列,子序列不要求是连续的.例如: Input:4,6,9,6,7,6,3,8,10:Output:5 二.解决方法: 1.用动态规划的方法解决.从问题我们可以知道,我们最终得到的最长递增子序列,其任意一段子序列也是对应序列中的最长子序列.这样说可能不好理解,就以上面的例子来说: 最长子序列为:4,6, 7, 8, 10.在这段子序列的子序列里选一个,例如:4,6,7.则4,6,7也是4,6,9,6,7,6,3这段序列的最长子序列. 对于动

HUD 5773 LIS(最长上升序列)

***关于lower_bound()的用法参见:http://blog.csdn.net/niushuai666/article/details/6734403*** #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<cctype> #include<queue> #include

poj 2533 LIS(最长上升序列)

***一道裸题, 思路:在g数组内往里加元素,一直扩大这个数组,每次查询的时候,用二分查找,时间复杂度O(nlog(n)) *** #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<cctype> #include<queue> #include<vector> #in

最长增长序列的长度(LIS)

我最早的思路是反过来遍历,结果总是不对.因为老是觉得动态规划就是列递归,所以一心琢磨着怎样递归,导致一直不对. 正确的思路应该是什么呢?应该是尝试用符号表示其最优的状态和其子状态,然后找出状态之间转移的方法.最后实现这个方法. 最长增长序列的最优状态是什么样子呢?既然是最长,肯定是要容纳尽可能多的元素,怎样容纳尽可能多的元素呢?那就是较小值尽可能小. 那么遍历到的新元素就存在两种情况: 1. 新元素比已知当前 LIS  中的每个元素都要大,那毫无疑问应该加入 LIS. 2. 新元素比当前 LIS

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<

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: 然后输出

zoj1986 Bridging Signals (dp,最长递增序列,LIS)

A - Bridging Signals Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu Submit Status Practice ZOJ 1986 Description 'Oh no, they've done it again', cries the chief designer at the Waferland chip factory. Once more the routing designer

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