P1136 迎接仪式题解
先读题,这题显然是一道 DP 题;
于是,我们设计状态:
若交换的字符串为 "zz" :
若交换的字符串为 "zj":
若交换的字符串为 "jj":
接下来就是预处理:
如果交换的次数如果大于
于是,我们把所有设为最小(负无穷)把前两位设为
这样有效状态就会转移。
还有一点,循环中会越界,因此
注意乱开 long long 会 MLE 。
上代码!
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 505
using namespace std;
int dp[N][160][160],n,kk,ans;
char s[N],zz='z',jj='j';
signed main(){
scanf("%d%d",&n,&kk);
scanf("%s",s+1);
if(kk-1){
memset(dp,-0x3f,sizeof(dp));
dp[1][0][0]=dp[0][0][0]=0;
}
for(int i=2;i<=n;i++){
for(int j=0;j<=kk;j++){
for(int k=0;k<=kk;k++){
dp[i][j][k]=dp[i-1][j][k];
char a=s[i-1],b=s[i];
if(a==jj&&b==zz)dp[i][j][k]=dp[i-2][j][k]+1;
if(a==zz&&b==zz&&j)dp[i][j][k]=dp[i-2][j-1][k]+1;
if(a==zz&&b==jj&&j&&k)dp[i][j][k]=dp[i-2][j-1][k-1]+1;
if(a==jj&&b==jj&&k)dp[i][j][k]=dp[i-2][j][k-1]+1;
if(j==k&&j&&k)ans=max(dp[i][j][k],ans);
}
}
}
printf("%d",ans);
return 0;
}