Задача на рекурсию про лесенку из кубиков [закрыт]

128
10 ноября 2019, 12:40

Эта тема не вопрос, а работающее решение данной задачи в рекурсивном виде и оно ищет максимальную высоту лесенки, ничего больше. Как заметили в комментариях можно решить эту задачу через арифметическую прогрессию. Лесенкой называется набор кубиков, в котором каждый верхний слой содержит кубиков меньше, чем в предыдущем. Требуется написать программу вычисляющую число лесенок из N кубиков. Очень долго искал в интернете какой-то адекватно работающий вариант и все же решил сделать сам и помочь кому-то со схожей проблемой. Публикую решение ниже. Для тех, кто хочет разобраться. Сначала самым первым слоем является только один кубик, в последующих итерациях создаётся слой длины больший на 1, чем предыдущий. И так до тех пор, пока не достигается результат.

int layersCount = 1;
int Stairs(int n, int previousLayer)
{
    int thisLayer=0;
    while (thisLayer - previousLayer !=1 && n - (thisLayer + previousLayer)>0)
        thisLayer++;
    if (thisLayer - previousLayer == 1) layersCount += 1;
    if (n - thisLayer-previousLayer > 0)
        return Stairs(n - previousLayer, thisLayer);
    else
        return layersCount;
}
int main()
{
    int n;
    std::cin >> n;
    std::cout << Stairs(n,1);
}
Answer 1

Округленное вниз положительное решение квадратного уравнения:

(k + 1) * k / 2 = n
k = floor((-1 + sqrt(1 + 8 * n)) / 2)

(Привет от маленького Гаусса.)

Answer 2

Задачи "ищет максимальную высоту лесенки" и "число лесенок из N кубиков" - разные.

Отвечу на вторую, т.к. про неё написано "требуется найти", и приведена более-менее чёткая формулировка:

Лесенкой называется набор кубиков, в котором каждый верхний слой содержит кубиков меньше, чем в предыдущем. Требуется написать программу, вычисляющую число лесенок из N кубиков.

Это число разбиений (partitions) N на различные слагаемые (1, 1, 2, 2, 3, 4, 5, 6, 8, 10, 12, 15, 18, 22..)

import functools
@functools.lru_cache(maxsize=None)   #простейшая мемоизация
def growparts(n, last):
    if n == 0:
        return 1
    result = 0
    for i in range(last + 1, n + 1):
        result += growparts(n - i, i)
    return result
for k in range(15):
    print(k, growparts(k, 0))
READ ALSO
Не считывает файл до конца? [закрыт]

Не считывает файл до конца? [закрыт]

Необходимая инфа(файл) для работы проги messagetxt

105
Создание очереди из структур

Создание очереди из структур

Есть у меня база данных, я считал с этой базы данные, занес их в Persone(500 раз) и теперь мне надо поместить их в очередь, но что-то у меня не получается...

125
Чтение и запись членов union

Чтение и запись членов union

Никак не могу найти однозначный ответ на следующий вопрос

111
С++/WinAPI: GetOpenFileName крашит программу

С++/WinAPI: GetOpenFileName крашит программу

При выполнении GetOpenFileName иногда крашит программу с ошибкой:

173