Educational Codeforces Round 97 (Rated for Div. 2)【ABCD】
比赛链接:https://codeforces.com/contest/1437
A. Marketing Scheme
题解
令 \(l = \frac{a}{2}\),那么如果 \(r < a\),每个顾客都会买更多猫粮。
代码
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
int l, r;
cin >> l >> r;
cout << (r < 2 * l ? "YES" : "NO") << "\n";
}
return 0;
}
B. Reverse Binary Strings
题解
如果有一个连续 \(0\) 或 \(1\) 区间长度大于 \(1\),那么多出来的长度中的每个数都是需要翻转的。答案即连续 \(0\) 或 \(1\) 区间多出长度之和的最大值。
代码
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
string s;
cin >> s;
int ans[2] = {};
for (int i = 0; i < n; ) {
int j = i + 1;
while (j < n and s[j] == s[i]) ++j;
ans[s[i] - '0'] += j - i - 1;
i = j;
}
cout << max(ans[0], ans[1]) << "\n";
}
return 0;
}
C. Chef Monocarp
题解一
\(dp_{ij}\) 的含义为 \(i\) 个点放前 \(j\) 个数的最小花费。
代码
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
vector<int> t(n);
for (auto &x : t) cin >> x;
sort(t.begin(), t.end());
vector<vector<int>> dp(2 * n + 1, vector<int>(n + 1, 1e9));
for (int i = 0; i < 2 * n + 1; i++)
dp[i][0] = 0;
for (int i = 1; i <= 2 * n; i++) {
for (int j = 1; j <= n; j++) {
dp[i][j] = min(dp[i - 1][j], dp[i - 1][j - 1] + abs(t[j - 1] - i));
}
}
cout << dp[2 * n][n] << "\n";
}
return 0;
}
题解二
由于每层的状态取决于上一层,所以可以倒序遍历,空间复杂度因此由 \(S_{(n^2)}\) 优化至 \(S_{(n)}\) 。
代码
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
vector<int> t(n);
for (auto &x : t) cin >> x;
sort(t.begin(), t.end());
vector<int> dp(n + 1, 1e9);
dp[0] = 0;
for (int i = 1; i <= 2 * n; i++) {
for (int j = n; j >= 1; j--) {
dp[j] = min(dp[j], dp[j - 1] + abs(t[j - 1] - i));
}
}
cout << dp[n] << "\n";
}
return 0;
}
D. Minimal Height Tree
题解
将 \(bfs\) 序列分割为一个个连续递增区间,每个递增区间都可以归于上一层的一个结点。
代码
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
vector<int> a(n);
for (auto &x : a) cin >> x;
vector<int> seg;
for (int i = 1; i < n; ) {
int j = i + 1;
while (j < n and a[j] > a[j - 1]) ++j;
seg.push_back(j - i);
i = j;
}
int height = 0;
int prv = 1, nxt = 0;
for (int i = 0; i < int(seg.size()); ) {
++height;
nxt = accumulate(seg.begin() + i, min(seg.end(), seg.begin() + i + prv), 0);
i += prv;
prv = nxt;
}
cout << height << "\n";
}
return 0;
}