求数组中最长递增子序列(编程之美2.16)

来源:互联网 发布:淘宝客pid怎么获取 编辑:程序博客网 时间:2024/05/06 20:47
#ifndef _LGONGEST_INCREMENTAL_SEQUENCE_H_ #define _LGONGEST_INCREMENTAL_SEQUENCE_H_#include <vector>#include <algorithm>using namespace std;//编程之美2.16//最长递增子序列,使用动态规划的时间复杂度为O(n^2).//但是通过剪枝可以大大减少比较的次数。//主要思想是://1.可以使用一个结构来记录一个长度串中的末位信息,而不是一个元素对应一个长度信息。//这样,长度串跟元素是一对多的关系。//如果LIS[i]有多个序列,比如如果LIS[2]的序列可能是-1,2和1,10//那么对于序列中的下一个值3,4,5,6,12来说,它们都能使用-1,2来构成更长的串,//所以LIS[i]应该是长度为i的串中末尾数字的最小值//2.应该看到,如果i<j,那么LIS[i]<LIS[j],为什么这么说呢?因为如果LIS[i] >= LIS[j]//的话,我们就可以把LIS[j]放入到LIS[i]的末尾,从而LIS[j] == LIS[i]矛盾了。template<typename T>struct longest_incremental_sequence_comparator{const bool operator()(const T& t1, const T& t2) const{return t1 < t2;}};template<typename T>size_t longest_incremental_sequence(const vector<T>& array){vector<T> LIS;LIS.reserve(array.size());longest_incremental_sequence_comparator<T> c;for (size_t i = 0; i != array.size(); i++){//const T& t = array[i];//由于是有序的,所以使用upper_bound找到第一个比它小的vector<T>::iterator itr = upper_bound(LIS.begin(), LIS.end(), t, c);
if (itr == LIS.end()){//最长子序列增加了LIS.push_back(t);}else{//更新它的下一个if (*itr > t){//*itr = t;}}}return LIS.size();}void test_longest_incremental_sequence(){int arr[] = {1,-1,2,-3,4,-5,6,7};vector<int> a(arr, arr+sizeof(arr)/sizeof(arr[0]));size_t max_length = longest_incremental_sequence(a);cout << max_length << endl;}#endif


原创粉丝点击