Here is how to simply find longest increasing/decreasing subsequence in Mathematica:
 LIS[list_] := LongestCommonSequence[Sort[list], list];
 input={0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15};
 LIS[input]
 -1*LIS[-1*input]
Output:
{0, 2, 6, 9, 11, 15}
{12, 10, 9, 5, 3}
Mathematica has also LongestIncreasingSubsequence function in the Combinatorica` libary. If you do not have Mathematica you can query the WolframAlpha.
  C++ O(nlogn) solution
  
  There's also an O(nlogn) solution based on some
  observations. Let Ai,j be the smallest
  possible tail out of all increasing
  subsequences of length j using
  elements a1, a2, ... , ai. Observe that, for any
  particular i, Ai,1, Ai,2, ... , Ai,j. This suggests that if
  we want the longest subsequence that
  ends with ai + 1, we only need to look
  for a j such that Ai,j < ai + 1 < =
  Ai,j + 1 and the length will be j + 1.
  Notice that in this case, Ai + 1,j + 1
  will be equal to ai + 1, and all Ai +
  1,k will be equal to Ai,k for k!=j+1.
  Furthermore, there is at most one
  difference between the set Ai and the
  set Ai + 1, which is caused by this
  search. Since A is always ordered in
  increasing order, and the operation
  does not change this ordering, we can
  do a binary search for every single a1, a2, ... , an.
  
  Implementation C++ (O(nlogn) algorithm)
#include <vector>
using namespace std;
/* Finds longest strictly increasing subsequence. O(n log k) algorithm. */
void find_lis(vector<int> &a, vector<int> &b)
{
  vector<int> p(a.size());
  int u, v;
  if (a.empty()) return;
  b.push_back(0);
  for (size_t i = 1; i < a.size(); i++) {
      if (a[b.back()] < a[i]) {
          p[i] = b.back();
          b.push_back(i);
          continue;
      }
      for (u = 0, v = b.size()-1; u < v;) {
          int c = (u + v) / 2;
          if (a[b[c]] < a[i]) u=c+1; else v=c;
      }
      if (a[i] < a[b[u]]) {
          if (u > 0) p[i] = b[u-1];
          b[u] = i;
      }   
  }
  for (u = b.size(), v = b.back(); u--; v = p[v]) b[u] = v;
}
/* Example of usage: */
#include <cstdio>
int main()
{
  int a[] = { 1, 9, 3, 8, 11, 4, 5, 6, 4, 19, 7, 1, 7 };
  vector<int> seq(a, a+sizeof(a)/sizeof(a[0]));
  vector<int> lis;
        find_lis(seq, lis);
  for (size_t i = 0; i < lis.size(); i++)
      printf("%d ", seq[lis[i]]);
        printf("\n");    
  return 0;
}
Source: link
I have rewritten the C++ implementation to Java a while ago, and can confirm it works. Vector alternative in python is List. But if you want to test it yourself, here is link for online compiler with example implementation loaded: link
Example data is: { 1, 9, 3, 8, 11, 4, 5, 6, 4, 19, 7, 1, 7 }
and answer: 1 3 4 5 6 7.