ограничение по времени на тест2 секунды ограничени...
बनाया गया: 21 अप्रैल 2026
बनाया गया: 21 अप्रैल 2026
ограничение по времени на тест2 секунды
ограничение по памяти на тест512 мегабайт
Есть таблица из 2×n
клеток. Каждая ячейка таблицы раскрашена в красный или черный цвет. Вы хотите перекрасить некоторые ячейки этой таблицы таким образом, чтобы существовал хотя бы один способ разбить все ячейки на n
пар так, чтобы выполнялись условия:
ячейки в каждой паре одного цвета;
ячейки в каждой паре являются соседними по стороне.
Какое минимальное количество ячеек необходимо для этого перекрасить?
Входные данные
Каждый тест состоит из нескольких наборов входных данных. В первой строке находится одно целое число t
(1≤t≤104
) — количество наборов входных данных. Далее следует описание наборов входных данных.
Первая строка каждого набора входных данных содержит одно целое число n
(1≤n≤2⋅105
).
Вторая и третья строки каждого набора входных данных описывают цвета ячеек. Каждая строка состоит из букв «R» и «B» и имеет длину n
.
Дополнительные ограничения на входные данные:
сумма n
по всем наборам входных данных не превосходит 2⋅105
.
Выходные данные
Для каждого набора входных данных выведите одно целое число — минимальное количество ячеек, которые нужно перекрасить.
Пример
Входные данныеСкопировать
5
1
R
B
2
BR
BR
3
RBR
BRB
4
RRBB
BBRB
5
RBRBR
BBBRB
Выходные данныеСкопировать
1
0
3
1
4
Примечание
Рассмотрим 3
-й пример. Одним из вариантов является окраска всех ячеек в один цвет, что требует перекраски 3
-х ячеек.
В 4
-м примере одним из вариантов допустимой перекраски является
RRBB
BBRR
реши на с++
Да. Здесь достаточно обычного DP по столбцам.
Разбиение доски 2 × n на соседние по стороне пары — это просто замощение доминошками:
Для каждой доминошки нужно, чтобы обе клетки стали одного цвета.
Минимальная цена для одной пары:
0, если цвета уже совпадают,1, если разные.Пусть строки — a и b.
iСостоит из a[i] и b[i].
textvert(i) = (a[i] != b[i] ? 1 : 0)
i-1 и iНужно сделать одинаковыми:
a[i-1] и a[i],b[i-1] и b[i].Цена:
texthor(i-1, i) = (a[i-1] != a[i] ? 1 : 0) + (b[i-1] != b[i] ? 1 : 0)
dp[i] — минимальное число перекрашиваний для первых i столбцов.
Переходы:
i:textdp[i] = dp[i-1] + vert(i)
i-1 и i:textdp[i] = dp[i-2] + hor(i-1, i)
Итого:
textdp[i] = min(dp[i-1] + vert(i), dp[i-2] + hor(i-1, i))
Любое корректное разбиение первых i столбцов заканчивается ровно одним из двух способов:
Других вариантов для замощения полосы 2 × i нет.
Значит, оптимальный ответ для i столбцов получается из оптимального ответа на меньшем префиксе плюс стоимость последнего шага. Это и есть DP выше.
На один тест: O(n)
По всем тестам: O(sum n)
Память: O(n), можно даже O(1).
cpp#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 a, b; cin >> a >> b; vector<int> dp(n + 1, (int)1e9); dp[0] = 0; for (int i = 1; i <= n; ++i) { // Вертикальная доминошка в столбце i int vert = (a[i - 1] != b[i - 1]); dp[i] = min(dp[i], dp[i - 1] + vert); // Две горизонтальные доминошки на столбцах i-1 и i if (i >= 2) { int hor = (a[i - 2] != a[i - 1]) + (b[i - 2] != b[i - 1]); dp[i] = min(dp[i], dp[i - 2] + hor); } } cout << dp[n] << '\n'; } return 0; }
Если хочешь, я могу еще написать короткое объяснение в стиле Codeforces editorial.