题解:CF2143D1 Inversion Graph Coloring (Easy Version)

· · 题解

若出现 i < j < k, b_i > b_j > b_k,就连成了一个奇环,这是无法红蓝染色的。也就是 b 的最长下降子序列 \textrm{LDS} \le 2。而这样,b 一定可以由最多 2 条上升子序列组成。

考虑动态规划,设 f_{i, x, y} 表示考虑了 a 的前 i 个元素,选择的子序列的第一条上升子序列最后一个元素为 x,第二条上升子序列最后一个元素为 y(y < x) 的方案数,若 y = 0,表示还没出现第二条。

注意 x, y 对应的是 ,而不是下标(当然,用下标表示也可以,但这没有用到 a_i\in[1,n] 的性质,也不利于 Hard Version 的思考)。

考虑转移,现在考虑 a_i

边界条件:f_{0, 0, 0} = 1

答案

\sum_{x=1}^n\sum_{y = 0}^{x-1} f_{n,x,y} :::success[实现] ```cpp line-numbers #include <bits/stdc++.h> using namespace std; using ll = long long; using pii = pair<int, int>; #ifdef ONLINE_JUDGE #define debug(...) 0 #else #define debug(...) fprintf(stderr, __VA_ARGS__), fflush(stderr) #endif int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int tt; cin >> tt; while (tt--) { constexpr int mod = 1e9 + 7; int n; cin >> n; vector<int> a(n + 1); for (int i = 1; i <= n; i++) cin >> a[i]; vector<vector<vector<int>>> f(n + 1, vector<vector<int>>(n + 1, vector<int>(n + 1))); f[0][0][0] = 1; for (int i = 1; i <= n; i++) { for (int j = 0; j <= n; j++) for (int k = 0; k <= j; k++) { f[i][j][k] = (f[i][j][k] + f[i - 1][j][k]) % mod; if (j <= a[i]) f[i][a[i]][k] = (f[i][a[i]][k] + f[i - 1][j][k]) % mod; else if (k <= a[i]) f[i][j][a[i]] = (f[i][j][a[i]] + f[i - 1][j][k]) % mod; } } int ans = 0; for (int j = 0; j <= n; j++) for (int k = 0; k <= j; k++) ans = (ans + f[n][j][k]) % mod; cout << ans << "\n"; } return 0; } ``` :::