Codeforces Beta Round #17 C. Balance DP

C. Balance

题目链接

http://codeforces.com/contest/17/problem/C

题面

Nick likes strings very much, he likes to rotate them, sort them, rearrange characters within a string… Once he wrote a random string of characters a, b, c on a piece of paper and began to perform the following operations:

to take two adjacent characters and replace the second character with the first one,
to take two adjacent characters and replace the first character with the second one
To understand these actions better, let’s take a look at a string «abc». All of the following strings can be obtained by performing one of the described operations on «abc»: «bbc», «abb», «acc». Let’s denote the frequency of a character for each of the characters a, b and c as the number of occurrences of this character in the string. For example, for string «abc»: |a| = 1, |b| = 1, |c| = 1, and for string «bbc»: |a| = 0, |b| = 2, |c| = 1.

While performing the described operations, Nick sometimes got balanced strings. Let’s say that a string is balanced, if the frequencies of each character differ by at most 1. That is  - 1 ≤ |a| - |b| ≤ 1,  - 1 ≤ |a| - |c| ≤ 1 и  - 1 ≤ |b| - |c| ≤ 1.

Would you help Nick find the number of different balanced strings that can be obtained by performing the operations described above, perhaps multiple times, on the given string s. This number should be calculated modulo 51123987.

输入

The first line contains integer n (1 ≤ n ≤ 150) — the length of the given string s. Next line contains the given string s. The initial string can be balanced as well, in this case it should be counted too. The given string s consists only of characters a, b and c.

输出

Output the only number — the number of different balanced strings that can be obtained by performing the described operations, perhaps multiple times, on the given string s, modulo 51123987.

样例输入

4
abca

样例输出

7

题意

你可以使得一个元素变成他周围的元素的颜色,可以改变无数次,现在给你一个串,问你一共有多少种方案,使得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 的

代码

#include<bits/stdc++.h>
using namespace std;
const int mod = 51123987;
int dp[152][52][52][52],n,nxt[152][3];
string s;
void add(int &a,int b){
    a = a+b;
    if(a>=mod)a%=mod;
}
int main()
{
    scanf("%d",&n);
    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(b-c)<=1&&abs(a-c)<=1&&abs(b-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);
}
    原文作者:qscqesze
    原文地址: https://www.cnblogs.com/qscqesze/p/6173531.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞