1 条题解
-
0
自动搬运
来自洛谷,原作者为

hzoi_liuchang
AFO搬运于
2025-08-24 21:21:22,当前版本为作者最后更新于2020-07-15 19:15:05,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
分析
我们设为遍历了字符串的前位,改变了个和个,并且当前的这一位为所能达到的最大价值
设为遍历了字符串的前位,改变了个和个,并且当前的这一位为所能达到的最大价值
我们先来考虑
如果该字符串的第位本来是,那么我们把它改为后,必定不会与前面的字符组成,而且必定会花费一次修改操作
因此当前的最大值应该在前面的字符变为或变为中取
$f[i][j][k][0]=max(f[i-1][j][k-1][0],f[i-1][j][k-1][1]);$
如果该字符串的第位本来是,那么我们就不需要进行修改操作
但是,当前的字符仍然不会与前面的字符组成
所以当前的最大值还应该在前面的字符变为或变为中取
$f[i][j][k][0]=max(f[i-1][j][k][0],f[i-1][j][k][1]);$
接下来我们再考虑
如果该字符串的第位本来是,那么如果上一位的字符为,那么又可以组成一个,如果上一位为,则不能组成
$f[i][j][k][1]=max(f[i-1][j][k][0]+1,f[i-1][j][k][1]);$
如果该字符串的第位本来是,那么我们就需要进行一次修改操作
$f[i][j][k][1]=max(f[i-1][j-1][k][0]+1,f[i-1][j-1][k][1]);$
最后我们再在和相等的方案中取一个最大值即可
代码
#include<bits/stdc++.h> using namespace std; const int maxn=505,maxk=105; int n,m,f[maxn][maxk][maxk][3]; char s[maxn]; int main(){ scanf("%d%d%s",&n,&m,s+1); memset(f,128,sizeof(f)); f[0][0][0][1]=0; for(int i=1;i<=n;i++){ for(int j=0;j<=m;j++){ for(int k=0;k<=m;k++){ if(s[i]=='z'){ f[i][j][k][1]=max(f[i-1][j][k][0]+1,f[i-1][j][k][1]); if(k) f[i][j][k][0]=max(f[i-1][j][k-1][0],f[i-1][j][k-1][1]); } else { f[i][j][k][0]=max(f[i-1][j][k][0],f[i-1][j][k][1]); if(j) f[i][j][k][1]=max(f[i-1][j-1][k][0]+1,f[i-1][j-1][k][1]); } } } } int ans=0; for(int i=0;i<=m;i++){ ans=max(ans,max(f[n][i][i][1],f[n][i][i][0])); } printf("%d\n",ans); return 0; }
- 1
信息
- ID
- 138
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 5
- 标签
- 递交数
- 1
- 已通过
- 0
- 上传者