题意:
给定长度为n的串S,
如果S(i)等于’L’,说明第i个人面朝左边,如果是’R’则面朝右边。
如果存在S(i)和S(i+1)方向相同,那么获得权值1,
给定k,你最多可以进行K次操作:
选择一个L和R,将S[L,R]内的所有字符翻转,‘L’变成’R’,‘R’变成’L’。
问操作结束之后的最大权值是多少。
数据范围:n,k<=1e5
解法:
LLL这种全部一样的翻转之后权值不变,
只有R|LLL这种,翻转一遍之后会增加一个权值,
遇到R|LLL|R这种能增加两个权值.
其他情况下不增加了.
发现一次操作最多增加两个权值.
那么贪心一下就行了:
记录每个L|R和R|L的位置,然后贪心的翻转.
code:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define PI pair<int,int>
const int maxm=1e6+5;
char s[maxm];
int n,k;
signed main(){
cin>>n>>k;
scanf("%s",s+1);
int ans=0;
vector<int>rl,lr;
for(int i=2;i<=n;i++){
if(s[i]==s[i-1]){
ans++;
}else{
if(s[i]=='L'){
rl.push_back(i);
}else{
lr.push_back(i);
}
}
}
int len1=rl.size();
int len2=lr.size();
int c=0,cc=0;
vector<int>temp;
while(c<len1&&cc<len2&&k){//+2
int x=rl[c],y=lr[cc];
if(x<y){//R|LLL|R
ans+=2;
k--;
c++,cc++;
}else{//L|RRR|L
ans+=2;
k--;
c++,cc++;
}
}
//+1
while(c<len1)temp.push_back(rl[c++]);
while(cc<len2)temp.push_back(lr[cc++]);
ans+=min((int)temp.size(),k);
//
cout<<ans<<endl;
return 0;
}