题意:给定含有WL的序列,最多能将k的L变成W,问最大的分值,当有连续的W的时候后面的W加二,第一个W加1。
解题思路:
一开始想的是dp,dp复杂度过不去啊。。后来想着把所有夹在两个W之间得区间都排序,就没继续往下面想了,看了题解,发现贪心策略跟我差不多,策略:尽量往贴近W的位置修改L,因为这样对答案的贡献都是+2,在这个基础上如果往两个W之间填满了W答案会多增加1,那么我们要让1加的尽量多,我们把所有两个W之间的区间从大到小排序就行了,感言:还是太年轻啊。。。
AC代码:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
int t;
vector<int>ps;
vector<int>seg;
int main()
{
cin >> t;
while(t--)
{
ps.clear();
seg.clear();
int n,k;
cin>>n>>k;
string s;
cin>>s;
int ctl=count(s.begin(),s.end(),'L');
if(ctl==n)
{
cout<<max(0,2*k-1)<<endl;
}
else
{
for(int i=0;i<s.size();i++)
if(s[i]=='W')
ps.push_back(i);
int res=0;
for(int i=1;i<ps.size();i++)
if(ps[i]-ps[i-1]-1>0)
seg.push_back(ps[i]-ps[i-1]-1);
sort(seg.begin(),seg.end());
for(int i=0;i<s.size();i++)
{
if(!i)
res+=s[i]=='W';
else
if(s[i]=='W')
res+=(s[i-1]=='W'?2:1);
}
res+=min(k,ctl)*2;
for(int i=0;i<seg.size();i++)
{
int len=seg[i];
if(k>=len)
{
res++;
k-=len;
}
}
cout<<res<<endl;
}
}
}