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;
}


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