• 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
    ",ans);
    }
  • 相关阅读:
    char和QChar(Unicode的编码与内存里的值还不是一回事)
    ddd
    vim实用笔记
    设计思想
    await使用中的阻塞和并发
    单元测试
    C#简单实现贪吃蛇程序(LinQ + Entity)
    JS逗号、冒号与括号
    C#实现对文件目录的实时监控
    在线预览PDF
  • 原文地址:https://www.cnblogs.com/qscqesze/p/6173531.html
Copyright © 2020-2023  润新知