#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