输入包含两行。
第一行输入两个正整数
——墙的长度与小苯允许施法的最大次数。
第二行输入一个长度为
的字符串
,保证
仅由字符
与
组成。
输出一个正整数,表示满足要求的最小
。
5 2 WRWWR
2
小苯可以进行次操作,每次操作的长度必须在
以内。
一种可能的染色方式是:选择再选择
,操作后整面墙都会被染红,可以证明不存在单次操作比
更小的长度。
n, m = map(int, input().split()) wall = input() def can_paint(k): count = 0 i = 0 while i < n: # 找到当前位置右侧最近的白色格子 j = i while j < n and wall[j] == 'R': j += 1 if j == n: break end = min(j + k - 1, n - 1) i = end + 1 count += 1 return count <= m # 因为最少要涂一块,所以left = 1 left, right = 1, n while left < right: mid = (left + right) // 2 if can_paint(mid): right = mid else: left = mid + 1 # 检查一下是不是真的不需要涂 wuhu = [char for char in wall if char == 'W'] if wuhu == []: print(0) else: print(left)
#include <bits/stdc++.h> using namespace std; #define endl '\n' //#define inf 1e18 typedef long long ll; #define int long long int n, m; string s; bool check(int mid) { vector<int> dp(n + 1, 1e18); dp[0] = 0; for(int i = 1; i <= n; i++) { if(s[i] == 'R') { dp[i] = dp[i - 1]; } else { dp[i] = dp[max(0LL, i - mid)] + 1; } } return dp[n] <= m; } void solve() { cin >> n >> m >> s; s = " " + s; int l = 0, r = n; while(l < r) { int mid = (l + r) >> 1; if(check(mid)) r = mid; else l = mid + 1; } cout << l << endl; } /* 5 2 WRWWR 2 3 1 RRR 3 3 WWW */ signed main () { // init(minp, primes, m); // primes // init(); ios::sync_with_stdio(0); cin.tie(0), cout.tie(0); int _ = 1; // cin >> _; while(_ -- ) { solve(); } return 0; }