Longest Common Increasing Subsequence(LCIS)

Codeforces Beta Round 10 D

Codeforces 10 D. LCIS

dp[i][j] 為 a[1…i], b[1…j] 結尾為 b[j] 的 LCIS 的長度。

$$dp_{i, j} := \begin{cases} \max_{p < j, b_{p} < b_{j}} dp_{i - 1, p} + 1 &, a_{i} = b_{j} \\ dp_{i - 1, j} &, \text{otherwise}. \end{cases}$$

複雜度:O(nm),n, m 為兩序列長度。

 1#pragma GCC optimization ("O3")
 2#include<bits/stdc++.h>
 3using namespace std;
 4int main() {
 5    ios::sync_with_stdio(0), cin.tie(0);
 6    // INPUT
 7    int L[2];
 8    vector<int> v[2];
 9    for (int i = 0; i < 2; i++) {
10        cin >> L[i];
11        v[i].resize(L[i] + 1);
12        for (int j = 1; j <= L[i]; j++)
13            cin >> v[i][j];
14    }
15    // LCIS
16    vector<vector<int> > dp(L[0] + 1, vector<int>(L[1] + 1));
17    vector<vector<int> > par(L[0] + 1, vector<int>(L[1] + 1));
18    for (int i = 1; i <= L[0]; i++) {
19        int p = 0;
20        for (int j = 1; j <= L[1]; j++) {
21            if (v[0][i] == v[1][j]) {
22                dp[i][j] = dp[i - 1][p] + 1;
23                par[i][j] = p;
24            } else {
25                dp[i][j] = dp[i - 1][j];
26                par[i][j] = j;
27                if (v[0][i] > v[1][j] &&
28                    dp[i - 1][j] > dp[i - 1][p])
29                    p = j;
30            }
31        }
32    }
33    // BACKTRACKING
34    int p = 0;
35    for (int j = 1; j <= L[1]; j++)
36        if (dp[L[0]][p] < dp[L[0]][j])
37            p = j;
38    vector<int> ans;
39    for (int i = L[0]; i > 0; i--) {
40        if (v[0][i] == v[1][p] && p != par[i][p])
41            ans.push_back(v[0][i]);
42        p = par[i][p];
43    }
44    cout << ans.size() << "\n";
45    for (int i = ans.size() - 1; i >= 0; i--)
46        cout << ans[i] << " \n"[!i];
47    return 0;
48}
Built with Hugo
Theme Stack designed by Jimmy