题目描述
给你一个长度为n且由a和b组成的字符串,你可以删除其中任意的部分(可以不删),使得删除后的子串“变化”次数小于等于m次且最长。
变化:如果a[i]!=a[i+1]则为一次变化。(且新的字符串的首字母必须是'a')
如果初始串全为b,则输出0。
变化:如果a[i]!=a[i+1]则为一次变化。(且新的字符串的首字母必须是'a')
如果初始串全为b,则输出0。
输入描述:
第一行输入两个数n,m。(1 <= n <= 105,0 <= m <= 10)
第二行输入一行长度为n且由a和b组成的字符串
输出描述:
输出一个数字表示最长长度
示例1
输入
8 2
aabbabab
输出
6
说明
原串可以变成aabbbb,只改变了一次,且长度最长。
题意
如上
题解
一看到这题就是Dp题,从变化次数m切入
这里j指变化次数,数组a是指最后放的是字符a的长度,b同理
a[j]=max(a[j]+1,b[j-1]+1),s[i] = 'a'(1<=j<=m+1)
b[j]=max(b[j]+1,a[j-1]+1),s[i] = 'b'
上面的意思是,如果s[i] = ‘a’,a[j]直接加上去,或者由b[j-1]通过变化加上去
这里由于新的字符串要求以‘a’开头,所以假设新串以‘b’通过变化得到为开始点
代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,m,a[],b[];
char s[];
for(int i=;i<=;i++)
a[i]=b[i]=-1e9;
cin>>n>>m;
m++;b[]=;
scanf("%s",s+);
for(int i=;i<=n;++i)
for(int j=m;j;--j)
if(s[i]=='a')
a[j]=max(a[j]+,b[j-]+);
else
b[j]=max(b[j]+,a[j-]+);
int ans=;
for(int i=m;i;--i)
ans=max(ans,max(a[i],b[i]));
cout<<ans;
return ;
}