hdu 1502

题意:给一个n,求出一个长度为3n,由A,B,C组合而成的字符串的种类数。

组合条件:

1。字符串中个数:A= B = C

2。字符串的任意前缀,数量A >= B >= C。

我们可以用动态规划来做,dp[i][j][k]表示,此字符串中A的数量为i,B的数量为j, C的数量为k。那么dp[i][j][k] = dp[i - 1][j][k] + dp[i][j - 1][k] + dp[i][j][k - 1]。

其中应该满足的条件是i >= j >= k。

由于数据太大,需要高进度处理,量太大而范围小,需要打表。


#include<cstdio>
#include<cstring>
const int maxn = 60 + 5;
const int maxt = 100;
char dp[maxn][maxn][maxn][maxt];
int main()
{
    //memset(dp, 0, sizeof(dp));
    dp[0][0][0][1] = 1;
    for(int i = 1; i < maxn; i++)
        for(int j = 0; j <= i; j++)
            for(int k = 0; k <= j; k++)
            {
                for(int t = 1; t < maxt - 2; t++)
                {
                    dp[i][j][k][t] += dp[i - 1][j][k][t];
                    if(j >= 1) dp[i][j][k][t] += dp[i][j - 1][k][t];
                    if(k >= 1) dp[i][j][k][t] += dp[i][j][k - 1][t];
                    dp[i][j][k][t + 1] += dp[i][j][k][t] / 10;
                    dp[i][j][k][t] = dp[i][j][k][t] % 10;
                }
                if(i == j && j == k)
                {
                    int temp = maxt;
                    while(!dp[i][j][k][temp]) temp--;
                    dp[i][j][k][0] = temp;
                    //printf("%d %d %d %d\n\n", i, j, k, temp);
                }
            }
    int m;
    while(scanf("%d", &m) == 1)
    {
        int p = dp[m][m][m][0];
        //printf("%d\n", p);
        for(int i = p; i >= 1; i--) printf("%c", dp[m][m][m][i] + '0');
        printf("\n\n");
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章