题意:给一个字符串,只有ABC组成,并且A、B、C的个数都是n(0<n<=60)个,问你存在多少个组合方式满足条件:任以前X项中,A的个数大于等于B的个数,B的个数大于等于C的个数。
解题:设函数dp[i][j][k]表示该序列中有i个A,j个B,k个C组成,则dp[i][j][k]是有dp[i-1][j][k],dp[i][j-1][k],dp[i][j][k-1]这三个添加过来的,所以动态转移方程式
dp[i][j][k]=dp[i-1][j][k]+dp[i][j-1][k]+dp[i][j][k-1];同时注意,dp的结果很大,要用到大数。
将串分成三种情况:末尾为A,末尾为B,末尾为C。则dp[i][t][k]=dp[i-1][t][k]+dp[i][t-1][k]+dp[i][t][k-1]。
初始化,A的数目为0和1时,符合要求的字符串数目,然后由2开始求解当A的数目大于2时的结果
dp[0][0][0] = 1
dp[1][0][0] = 1
dp[1][1][0] = 1
dp[1][1][1] = 1
使用Python 打表
def getAns(n):
if n < 2:
return 1
dp = [
[
[0 for i in range(n + 1)]
for j in range(n + 1)
]
for k in range(n + 1)
]
for i in range(n + 1):
dp[i][0][0] = 1
dp[1][1][0] = 1
dp[1][1][1] = 1
for i in range(2, n + 1):
for j in range(i + 1):
for k in range(j + 1):
dp[i][j][k] = dp[i - 1][j][k] + dp[i][j - 1][k] + dp[i][j][k - 1]
return dp[n][n][n]
for i in range(61):
print(i, getAns(i))