[luoguP1136] 迎接仪式(DP)

Posted 蒟蒻zht的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[luoguP1136] 迎接仪式(DP)相关的知识,希望对你有一定的参考价值。

传送门

 

每个字母只有两种选择,变成另一个或者不变。

所以f[i][j][k]表示前i个字母有j个j变成z,有k个z变成j

只需要比较j==k时的答案就行

#include <cstdio>
#include <cstring>
#define N 505
#define max(x, y) ((x) > (y) ? (x) : (y))

int n, m, ans;
char s[N];
int f[N][105][105];

int main()
{
	int i, j, k;
	scanf("%d %d", &n, &m);
	scanf("%s", s + 1);
	memset(f, -0x3f, sizeof(f));
	f[0][0][0] = f[1][0][0] = 0;
	s[1] == ‘j‘ ? f[1][1][0] = 0 : f[1][0][1] = 0;
	for(i = 2; i <= n; i++)
		for(j = 0; j <= m; j++)
			for(k = 0; k <= m; k++)
			{
				f[i][j][k] = f[i - 1][j][k];
				if(s[i - 1] == ‘j‘ && s[i] == ‘z‘) f[i][j][k] = max(f[i][j][k], f[i - 2][j][k] + 1);
				if(s[i - 1] == ‘j‘ && s[i] == ‘j‘ && j) f[i][j][k] = max(f[i][j][k], f[i - 2][j - 1][k] + 1);
				if(s[i - 1] == ‘z‘ && s[i] == ‘z‘ && k) f[i][j][k] = max(f[i][j][k], f[i - 2][j][k - 1] + 1);
				if(s[i - 1] == ‘z‘ && s[i] == ‘j‘ && j && k) f[i][j][k] = max(f[i][j][k], f[i - 2][j - 1][k - 1] + 1);
				if(j == k) ans = max(ans, f[i][j][k]);
			}
	printf("%d\n", ans);
	return 0;
}

  

以上是关于[luoguP1136] 迎接仪式(DP)的主要内容,如果未能解决你的问题,请参考以下文章

P1136 迎接仪式

P1136 迎接仪式

洛谷P1136 迎接仪式

2021record

Vijos1616 迎接仪式

那些神奇的DP建模