[題解][洛谷P1136] 迎接儀式

ZWZWW發表於2024-04-17

題目描述

對於一個由字母“j”和“z”組成的字串,可以任意交換兩個字元的位置不超過k次,求最多能出現多少個“jz”字串。

題解

動態規劃題。
設f[i][j][k][0/1]表示到第i位,前面交換了j個“j”,交換了k個“z”,且第i位是j(用0表示)或z(用1表示)。
當j=k時即為可行解。
為什麼需要用第四維統計:因為上一位的末尾是0或1會對下一位產生影響。上一位既有被更改的可能,也有沒有更改的可能,需分別計算。

程式碼

#include<bits/stdc++.h>
using namespace std;
int f[507][107][107][2];
int a[507];
int main(){
	memset(f,-1,sizeof f);
	int n,k;
	cin>>n>>k;
	string s;
    cin>>s;
	for(int i=1;i<=n;i++)a[i]= s[i-1]=='z';
	f[0][0][0][1]=0;
	for(int i=1;i<=n;i++)
		for(int p=0;p<=k;p++)
			for(int q=0;q<=k;q++){
				f[i][p][q][a[i]]=max(f[i-1][p][q][0]+a[i],f[i-1][p][q][1]);
				if(a[i]&&p)f[i][p][q][0]=max(f[i-1][p-1][q][1],f[i-1][p-1][q][0]);
				else if(!a[i]&&q)f[i][p][q][1]=max(f[i-1][p][q-1][0]+1,f[i-1][p][q-1][1]);
			}		
	int ans=0;
	for(int i=0;i<=k;i++)ans=max(ans,max(f[n][i][i][0],f[n][i][i][1]));
	cout<<ans<<endl;
}

相關文章