[algorithm] How to determine the longest increasing subsequence using dynamic programming?

Here are three steps of evaluating the problem from dynamic programming point of view:

  1. Recurrence definition: maxLength(i) == 1 + maxLength(j) where 0 < j < i and array[i] > array[j]
  2. Recurrence parameter boundary: there might be 0 to i - 1 sub-sequences passed as a paramter
  3. Evaluation order: as it is increasing sub-sequence, it has to be evaluated from 0 to n

If we take as an example sequence {0, 8, 2, 3, 7, 9}, at index:

  • [0] we'll get subsequence {0} as a base case
  • [1] we have 1 new subsequence {0, 8}
  • [2] trying to evaluate two new sequences {0, 8, 2} and {0, 2} by adding element at index 2 to existing sub-sequences - only one is valid, so adding third possible sequence {0, 2} only to parameters list ...

Here's the working C++11 code:

#include <iostream>
#include <vector>

int getLongestIncSub(const std::vector<int> &sequence, size_t index, std::vector<std::vector<int>> &sub) {
    if(index == 0) {
        sub.push_back(std::vector<int>{sequence[0]});
        return 1;
    }

    size_t longestSubSeq = getLongestIncSub(sequence, index - 1, sub);
    std::vector<std::vector<int>> tmpSubSeq;
    for(std::vector<int> &subSeq : sub) {
        if(subSeq[subSeq.size() - 1] < sequence[index]) {
            std::vector<int> newSeq(subSeq);
            newSeq.push_back(sequence[index]);
            longestSubSeq = std::max(longestSubSeq, newSeq.size());
            tmpSubSeq.push_back(newSeq);
        }
    }
    std::copy(tmpSubSeq.begin(), tmpSubSeq.end(),
              std::back_insert_iterator<std::vector<std::vector<int>>>(sub));

    return longestSubSeq;
}

int getLongestIncSub(const std::vector<int> &sequence) {
    std::vector<std::vector<int>> sub;
    return getLongestIncSub(sequence, sequence.size() - 1, sub);
}

int main()
{
    std::vector<int> seq{0, 8, 2, 3, 7, 9};
    std::cout << getLongestIncSub(seq);
    return 0;
}

Examples related to algorithm

How can I tell if an algorithm is efficient? Find the smallest positive integer that does not occur in a given sequence Efficiently getting all divisors of a given number Peak signal detection in realtime timeseries data What is the optimal algorithm for the game 2048? How can I sort a std::map first by value, then by key? Finding square root without using sqrt function? Fastest way to flatten / un-flatten nested JSON objects Mergesort with Python Find common substring between two strings

Examples related to computer-science

HTML5 Canvas background image What exactly does big ? notation represent? Fixed point vs Floating point number What are the differences between a program and an application? What do we mean by Byte array? How to determine the longest increasing subsequence using dynamic programming? What is "entropy and information gain"? What are the differences between NP, NP-Complete and NP-Hard? What is the difference between statically typed and dynamically typed languages? What is “2's Complement”?

Examples related to dynamic-programming

Find common substring between two strings Difference between Divide and Conquer Algo and Dynamic Programming What is the difference between bottom-up and top-down? How to determine the longest increasing subsequence using dynamic programming? What is dynamic programming?

Examples related to memoization

What is the difference between bottom-up and top-down? How to determine the longest increasing subsequence using dynamic programming? What is memoization and how can I use it in Python? Is there a decorator to simply cache function return values?

Examples related to lis

How to determine the longest increasing subsequence using dynamic programming?