题目描述
给你一个长度为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’通过变化得到为开始点
代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 int main() 4 { 5 int n,m,a[11],b[11]; 6 char s[100005]; 7 for(int i=0;i<=10;i++) 8 a[i]=b[i]=-1e9; 9 cin>>n>>m; 10 m++;b[0]=0; 11 scanf("%s",s+1); 12 for(int i=1;i<=n;++i) 13 for(int j=m;j;--j) 14 if(s[i]=='a') 15 a[j]=max(a[j]+1,b[j-1]+1); 16 else 17 b[j]=max(b[j]+1,a[j-1]+1); 18 int ans=0; 19 for(int i=m;i;--i) 20 ans=max(ans,max(a[i],b[i])); 21 cout<<ans; 22 return 0; 23 }