Longest Increasing Subsequence (LIS)
Longest increasing subsequence (LIS)
Problem statement
Given a sequence . It is required to find its increasing subsequence of maximum length.
For example, the longest increasing subsequence of is .
Longest increasing subsequence (LIS)
Given a sequence . It is required to find its increasing subsequence of maximum length.
For example, the longest increasing subsequence of is .
Create a copy of the sequence and sort it in increasing order. Let it be . Then the answer for the original problem is the LCS of sequences and .
Let denote the solution for the prefix of array of length under the condition that the element at position is included in the answer. I.e. the length of the longest increasing subsequence of where is included in the answer.
The base case is:
Now let us try to find transitions for the general case . Let us analyze the transitions. By definition of we must include in the answer. I.e. the last element of the increasing subsequence of the prefix is . Then we have two cases:
Therefore, we have the formula:
The answer will be the maximum value of among all .
Let us, for each non-base state, remember the best transition just as in the case of LCS. I.e. we will also create an array where we will store information about which transition was made. We know that has two different transitions:
After that we can reconstruct the answer. Find such an for which has the maximum value. And we will do the following until .
for (int i = 1; i <= n; i++) {
dp[i] = 1;
for (int j = 1; j < i; j++) {
if (a[j] < a[i]) {
dp[i] = max(dp[i], dp[j] + 1);
}
}
}
for (int i = 1; i <= n; i++) {
dp[i] = 1;
p[i] = 0;
for (int j = 1; j < i; j++) {
if (a[j] < a[i] && dp[j] + 1 > dp[i]) {
dp[i] = dp[j] + 1;
p[i] = j;
}
}
}
int x = 1;
for (int i = 1; i <= n; i++) {
if (dp[i] > dp[x]) {
x = i;
}
}
vector<int> res;
while (x > 0) {
res.push_back(a[x]);
x = p[x];
}
reverse(res.begin(), res.end());