Есть хитрый способ решить эту проблему.Представьте, что мы взяли n шаров и m - 1 коробок и поместили их в ряд длиной n + m - 1 (с коробками, смешанными среди шаров).Затем поместите каждый шарик в коробку справа и добавьте m -й ящик справа, в который попадут все оставшиеся шары.
Это дает расположение n шаров в m коробках.
Легко видеть, что есть одинаковое количестворасположение n шаров в последовательности с m - 1 коробками (первое изображение), так как имеются расположения n шаров в m коробках,(Чтобы пойти в одну сторону, поместите каждый шарик в коробку справа; для движения в другую сторону каждая коробка опустошает шарики в позиции слева от нее.) Каждое расположение на первом рисунке определяется позициями, в которые мы помещаемкоробки.Есть m - 1 коробка и n + m - 1 позиция, таким образом, есть n + m - 1 C m - 1 способов сделать это.
Так что вам просто нужен обычный алгоритм комбинаций ( см. Этот вопрос), чтобы сгенерировать возможные позиции для блоков, а затем взять разницу между последовательными позициями (меньше 1) для подсчета количества шаров в каждом блоке.
В Python это было бы очень просто, так как есть комбинаций алгоритм в стандартной библиотеке:
from itertools import combinations
def balls_in_boxes(n, m):
"""Generate combinations of n balls in m boxes.
>>> list(balls_in_boxes(4, 2))
[(0, 4), (1, 3), (2, 2), (3, 1), (4, 0)]
>>> list(balls_in_boxes(3, 3))
[(0, 0, 3), (0, 1, 2), (0, 2, 1), (0, 3, 0), (1, 0, 2), (1, 1, 1), (1, 2, 0), (2, 0, 1), (2, 1, 0), (3, 0, 0)]
"""
for c in combinations(range(n + m - 1), m - 1):
yield tuple(b - a - 1 for a, b in zip((-1,) + c, c + (n + m - 1,)))