CF2070C 学习笔记
二分太久没碰了,找一道题练练手。
谈谈做法
注意到题目中有这样一句话:
最终涂色的总惩罚值定义为所有错误颜色单元格的惩罚值的最大值。
如果没有错误颜色的单元格,总惩罚值为 0。
求可以达到的最小总惩罚值是多少?
求最大的最小的问题,我们考虑用二分解决。
谈谈细则
二分这种事情相信大家都不陌生,要说它难也就难在填 check 函数,考虑贪心来检查 \(mid\) 是否可行。
具体怎么实现呢?我们可以记录上一个字符为 \(pre\),在 \(a_i>mid\),且 \(s_{i-1}=B\),\(pre\) 与 \(s_{i-1}\) 不相等时对计数器进行累加,并更新 \(pre\) 的值。
谈谈实现
直接上代码。
/**********************************************************
* Author : dingziyang888
* Website : https://www.luogu.com.cn/problem/CF2070C
* Created Time : 2025/12/30 22:21
* FileName : CF2070C.cpp
* Warning!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* 1.MLE?
* 2.array size enough?
* 3.long long?
* 4.overflow long long?
* 5.multiple task cleaned?
* 6.freopen?
* 7.TLE?
* *******************************************************/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <iterator>
#include <map>
#include <unordered_map>
#include <queue>
#include <string>
#include <cstring>
#include <set>
#include <bitset>
#include <unordered_set>
#include <vector>
#include <deque>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <list>
#include <array>
#include <iterator>
#include <cmath>
#include <new>
#include <random>
#include <cfloat>
#include <cstdlib>
#include <climits>
#include <numeric>
#include <complex>
#include <ctime>
#include <chrono>
#include <thread>
#include <mutex>
#include <future>
#include <exception>
#include <stdexcept>
#include <cstdint>
#include <cassert>
#include <stack>
#include <cctype>
#define DEBUG
#define Ofile(s) freopen(s".in", "r", stdin), freopen (s".out", "w", stdout)
#define Cfile(s) fclose(stdin), fclose(stdout)
#define fast ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
using namespace std;
using ll = long long;
using ull = unsigned long long;
using lb = long double;
constexpr int mod = 998244353;
constexpr int maxn = 300005;
int t, n, k, ans;
int a[maxn];
string s;
bool check(int mid){
int sum = 0;
char pre = 'R';
for (int i = 1; i <= n; i++)
if (a[i] > mid){
if (s[i - 1] == 'B' and pre != s[i - 1]) ++sum;
pre = s[i - 1];
}
return sum <= k;
}
int main() {
cin >> t;
while (t--){
cin >> n >> k >> s;
for (int i = 1; i <= n; i++)
cin >> a[i];
int l = 0, r = 1e9;
ans = 0;
while (l <= r){
int mid = (l + r) >> 1;
if (check(mid)) ans = mid, r = mid - 1;
else l = mid + 1;
}
cout << ans << endl;
}
return 0;
}

浙公网安备 33010602011771号