LongestIncreasingSubsequence.cc 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. // Given a list of numbers of length n, this routine extracts a
  2. // longest increasing subsequence.
  3. //
  4. // Running time: O(n log n)
  5. //
  6. // INPUT: a vector of integers
  7. // OUTPUT: a vector containing the longest increasing subsequence
  8. #include <iostream>
  9. #include <vector>
  10. #include <algorithm>
  11. using namespace std;
  12. typedef vector<int> VI;
  13. typedef pair<int,int> PII;
  14. typedef vector<PII> VPII;
  15. #define STRICTLY_INCREASNG
  16. VI LongestIncreasingSubsequence(VI v) {
  17. VPII best;
  18. VI dad(v.size(), -1);
  19. for (int i = 0; i < v.size(); i++) {
  20. #ifdef STRICTLY_INCREASNG
  21. PII item = make_pair(v[i], 0);
  22. VPII::iterator it = lower_bound(best.begin(), best.end(), item);
  23. item.second = i;
  24. #else
  25. PII item = make_pair(v[i], i);
  26. VPII::iterator it = upper_bound(best.begin(), best.end(), item);
  27. #endif
  28. if (it == best.end()) {
  29. dad[i] = (best.size() == 0 ? -1 : best.back().second);
  30. best.push_back(item);
  31. } else {
  32. dad[i] = dad[it->second];
  33. *it = item;
  34. }
  35. }
  36. VI ret;
  37. for (int i = best.back().second; i >= 0; i = dad[i])
  38. ret.push_back(v[i]);
  39. reverse(ret.begin(), ret.end());
  40. return ret;
  41. }