1 条题解
-
0
重排文档(Reordering the Documents) 题解
思路分析
按题目要求使用对应数据结构与算法模拟/递推求解,注意数据范围边界与时间复杂度。
参考代码
#include <iostream> #include <vector> #include <numeric> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, m; if (!(cin >> n >> m)) return 0; vector<int> a(n + 1); for (int i = 1; i <= n; ++i) cin >> a[i]; vector<int> p(n + 1), col(n + 1, 0); iota(p.begin(), p.end(), 0); auto find = [&](auto& self, int x) -> int { if (p[x] == x) return x; int r = self(self, p[x]); col[x] ^= col[p[x]]; return p[x] = r; }; for (int i = 1; i <= n; ++i) { for (int j = i + 1; j <= n; ++j) { if (a[i] > a[j]) { int ri = find(find, i); int rj = find(find, j); if (ri == rj) { if (col[i] == col[j]) { cout << 0 << "\n"; return 0; } } else { p[ri] = rj; col[ri] = col[i] ^ col[j] ^ 1; } } } } vector<int> c0(n + 1, 0), c1(n + 1, 0); for (int i = 1; i <= n; ++i) { int r = find(find, i); if (col[i] == 0) c0[r]++; else c1[r]++; } const int MOD = 1000000007; vector<int> dp(m + 1, 0); dp[0] = 1; for (int i = 1; i <= n; ++i) { if (p[i] != i) continue; int s0 = c0[i], s1 = c1[i]; vector<int> ndp(m + 1, 0); for (int k = 0; k <= m; ++k) { if (!dp[k]) continue; if (k + s0 <= m) { ndp[k + s0] += dp[k]; if (ndp[k + s0] >= MOD) ndp[k + s0] -= MOD; } if (k + s1 <= m) { ndp[k + s1] += dp[k]; if (ndp[k + s1] >= MOD) ndp[k + s1] -= MOD; } } dp = move(ndp); } int ans = 0; for (int k = 0; k <= m; ++k) { if (n - k <= m) { ans += dp[k]; if (ans >= MOD) ans -= MOD; } } cout << ans << "\n"; return 0; }
信息
- ID
- 8833
- 时间
- 4000ms
- 内存
- 512MiB
- 难度
- (无)
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者