📜  n 位非递减整数的个数(1)

📅  最后修改于: 2023-12-03 15:17:49.561000             🧑  作者: Mango

计算n位非递减整数的个数

介绍

给定一个数n,本题要求计算由n位数字组成的非递减整数的个数。非递减整数是指从左到右所有的数字都不小于前面的数字,比如1234、1111都是非递减整数。

方法

我们可以使用组合数的思路来计算n位非递减整数的个数。

首先我们需要选择n个数字,这些数字可以是从0到9的任意数字。在这个过程中,我们可以允许数字重复出现,这种情况下也叫做允许重复的组合问题。

在每个数字选取的限制下,我们需要保证这些数字之间的顺序是非递减的。一种常见的处理方式是在这n个数字之间添加一个隔板,把数字分成n+1个部分,每个部分对应一个位数。在隔板的左边的数字都不超过隔板右边的数字。

比如说,我们选取的数字是1、2、3、4,那么我们可以用隔板法来表示所有的非递减序列:

1 | 2 3 4
1 2 | 3 4
1 2 3 | 4
1 | 2 | 3 4
1 | 2 3 | 4
1 2 | 3 | 4
1 | 2 | 3 | 4

在上述所有的方案中,隔板的位置代表了每个数字所在的位数。比如说,第一行的方案表示的就是一个4位的数,千位是1,百位是2,十位是3,个位是4。

由于我们需要选取n个数字和n-1个隔板,因此总共的方案数就是C(9+n,n-1)。

代码实现
def count_increasing_number(n: int) -> int:
    """
    计算n位非递减整数的个数
    """
    return math.comb(n + 9, n)

# 测试代码
assert count_increasing_number(1) == 10
assert count_increasing_number(2) == 55
assert count_increasing_number(3) == 220
总结

本题是一道非常典型的组合问题,使用隔板法可以很好地处理n个数字的非递减问题。这种思路也可以推广到其他类型的组合问题中。