0178 台阶数
* * * *
拉格朗日计划
* * * *
台阶数

考虑整数45656,可以看出它的每一对相邻数字之间都只差1。

把这样的数(任意一对相邻数字之间都只差1)称为台阶数,并把同时含有0到9这十个数字的数称为全数字数。

在小于$10^{40}$的数中,有多少个全数字台阶数?

本题难度:



解答

令$f(n,i,j,d)$为n位、含有数字i到j (包括i和j)、且以数字d结尾的数,其中$i\le d\le j$。

显然 $$f(n, d, d, d)=\begin{cases}1 & d>0 \\ 0 & d=0\end{cases}$$ (必须排除$d=0$,否则无法正确排除带有前导0的表示,这是容易忽视和出错的部分)

f的其它值可以递推计算 $$f(n, i, j, d)=\begin{cases}f(n-1, i, j, d-1)+f(n-1, i, j, d+1) & i< d < j \\ f(n-1, i, j, d+1)+f(n-1, i+1, j, d+1) & d=i \\ f(n-1, i, j, d-1)+f(n-1, i, j-1, d-1) & d=j\end{cases}$$ 这是因为若d在i和j之间,则其前一位可以是$d-1$或$d+1$。

若$d=i$,则根据i和j的定义其前一位只能是$d+1$,从而可能是由$f(n-1, i+1, j, d+1)$转移而得(表示前n-1位都不含d),也可能是由$f(n-1, i, j, d+1)$转移而得(表示d已经出现过)。

$d=j$的情况也类似。

结果是$126461847755$。

f=[[[[1 if i==j==k>0 else 0 for k in range(10)] for j in range(10)] for i in range(10)] for n in range(41)]

for n in range(2,41):
    for i in range(10):
        for j in range(i,10):
            for d in range(i,j+1):
                if i < d and d < j:
                    f[n][i][j][d]=f[n-1][i][j][d-1]+f[n-1][i][j][d+1]
                elif i==d and d < 9:
                    f[n][i][j][d]=f[n-1][i][j][d+1]+f[n-1][i+1][j][d+1]
                elif d>0:
                    f[n][i][j][d]=f[n-1][i][j][d-1]+f[n-1][i][j-1][d-1]

print sum(sum(f[n][0][9][d] for d in range(10)) for n in range(1,41))