題意:給一個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;
}