×

第一篇:P1136

题解补完计划:第一篇

原题题面

我们看到题,明显 DP 。我们定义 \(dp_{i,j,k,0/1}\) 表示当前在 \(i\) 我们一共调整了 \(j\) 个 \(j\),\(k\) 个 \(z\), 当前位是 $ j/z $那么转移很简单。

如果当前位是 \(j\):
对于 \(dp_{i,j,k,0} = \max(dp_{i-1,j,k,1} + 1, dp_{i-1, j, k, 0})\)
对于 \(dp_{i,j,k,1} = \max(dp_{i-1,j-1,k,1}, dp_{i-1,j-1,k,0})\)

如果当前位是 \(k\):
对于 \(dp_{i,j,k,0} = \max(dp_{i-1,j,k-1,1}+1, dp_{i-1, j,k-1,0})\)
对于 \(dp_{i,j,k,1} = \max(dp_{i-1,j,k,1}, dp_{i-1,j,k,0})\)

最后答案就是 $\max_{i=0}^{k} dp_{n,i,i,0/1} $。
因为调整 \(j\) 的次数等于调整 \(z\) 的次数。
代码:

#include<bits/stdc++.h>
using namespace std;
#define N 505
#define intl long long
#define For(i,a,b) for(intl i=a;i<=b;i++)
#define deo(i,a,b) for(intl i=a;i>=b;i--)
intl read() {
	intl x=0,k=1;char ch=getchar();
	while(!isdigit(ch)) {if(ch == '-') k=-1;ch=getchar();}
	while(isdigit(ch)) {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
	return x*k;
}
const intl K = 105;
intl dp[N][K][K][2];
intl n,k;
string s;
int main() {
	n = read(), k=read();
	cin >> s; s = ' ' + s;
	memset(dp,128,sizeof dp);
	dp[0][0][0][1] = 0; 
	For(i,1,n) {
		For(j,0,k) For(kk,0,k) {
			if(s[i] == 'j') {
				dp[i][j][kk][0] = max(dp[i-1][j][kk][0],dp[i-1][j][kk][1]);
				if(j) dp[i][j][kk][1] = max(dp[i-1][j-1][kk][0]+1,dp[i-1][j-1][kk][1]); 
			} else {
				dp[i][j][kk][1] = max(dp[i-1][j][kk][0]+1,dp[i-1][j][kk][1]);
				if(kk) dp[i][j][kk][0] = max(dp[i-1][j][kk-1][0],dp[i-1][j][kk-1][1]);
			}
		}
	}
	intl ans = 0;
	For(i,0,k) ans = max(ans,max(dp[n][i][i][1],dp[n][i][i][0]));
	printf("%lld\n",ans);
	return 0;
}
posted @ 2026-10-05 17:20  shiori123  阅读(6)  评论(0)    收藏  举报