51Nod 1134 最长递增子序列
Posted Dysania_l
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51Nod 1134 最长递增子序列相关的知识,希望对你有一定的参考价值。
给出长度为N的数组,找出这个数组的最长递增子序列。(递增子序列是指,子序列的元素是递增的)
例如:5 1 6 8 2 4 5 10,最长递增子序列是1 2 4 5 10。
Input
第1行:1个数N,N为序列的长度(2 <= N <= 50000) 第2 - N + 1行:每行1个数,对应序列的元素(-10^9 <= S[i] <= 10^9)
Output
输出最长递增子序列的长度。
Input示例
8 5 1 6 8 2 4 5 10
Output示例
5
思路:一开始没想那么多,直接dp,后面发现超时了,查了下最长上升子序列的解法发现有一种模拟栈操作的解法,时间复杂度为O(nlogn).套一下板子就行了,主要还是理解这份模板如何运行的
自己用代码测了下,当输入的数>top是,加入栈中并设为top,当输入的数<top时,找到栈中第一个大于它的数字并替换掉,这样虽然长度没有变化,但他的”潜力“变大了。最后top就是子序列最大长度了
算法主要还是贪心思想,用二分缩短时间。
实现代码:
#include <iostream> using namespace std; int main() { int i, j, n, top, temp; int stack[1001]; while(cin >> n) { top = 0; stack[0] = -1199999999; for (i = 0; i < n; i++) { cin >> temp; /* 比栈顶元素大数就入栈 */ if (temp > stack[top]) { stack[++top] = temp; } else { int low = 1, high = top; int mid; /* 二分检索栈中比temp大的第一个数 */ while(low <= high) { mid = (low + high) / 2; if (temp > stack[mid]) { low = mid + 1; } else { high = mid - 1; } } /* 用temp替换 */ stack[low] = temp; } } /* 最长序列数就是栈的大小 */ cout << top << endl; } return 0; }
以上是关于51Nod 1134 最长递增子序列的主要内容,如果未能解决你的问题,请参考以下文章