题目链接:​​这里​

题意:你可以使得一个元素变成他周围的元素的颜色,可以改变无数次,现在给你一个串,问你一共有多少种方案,使得a和b和c的个数相差不超过1。

题解:dp[i][a][b][c],表示考虑到第i个位置,当前有a个a,b个b,c个c 的方案数

然后转移就好了

维护一个next[i][3]表示下一个在哪儿。

虽然是4维dp,但是却是150 50 50 50 的

//CF 17C
#include <bits/stdc++.h>
using namespace std;
const int mod = 51123987;
int n, dp[152][52][52][52], nxt[152][3];
void add(int &x, int y){
x = x + y;
if(x>=mod) x%=mod;
}
int main()
{
scanf("%d", &n);
string s;
cin >> s;
for(int j = 0; j < 3; j++) nxt[n][j] = n;
for(int i = n - 1; i >= 0; i--){
for(int j = 0; j < 3; j++){
nxt[i][j] = nxt[i+1][j];
}
nxt[i][s[i]-'a'] = i;
}
dp[0][0][0][0] = 1;
int ans = 0;
for(int i = 0; i < n; i++){
for(int a = 0; a*3 <= n+2; a++){
for(int b = 0; b*3 <= n+2; b++){
for(int c = 0; c*3 <= n+2 && a+b+c<=n; c++){
if(dp[i][a][b][c]){
if(a+b+c==n&&abs(a-c)<=1&&abs(b-c)<=1&&abs(a-c)<=1) add(ans, dp[i][a][b][c]);
add(dp[nxt[i][0]][a+1][b][c], dp[i][a][b][c]);
add(dp[nxt[i][1]][a][b+1][c], dp[i][a][b][c]);
add(dp[nxt[i][2]][a][b][c+1], dp[i][a][b][c]);
}
}
}
}
}
printf("%d\n", ans);
return 0;
}