C/C++

Опишите, Пожалуйста, алгоритм, который решает данную задачу за разумное время

Возможно ли подобрать ровно n натуральных чисел таких, чтобы их сумма равнялась x, а произведение — y?
n <= 2000
x, y <= 10⁹
Раскладываем y на простые множители. Получим не более 29 множителей. Если хотя бы один множитель больше x - ответа не существует.

Комбинируем полученные множители в числа. Например, число 60 раскладывается на множители: 2, 2, 3, 5. Из них можно получить комбинации чисел:
60
2 30
3 20
4 15
5 12
6 10
2 2 15
2 3 10
2 5 6
3 4 5
2 2 3 5

Комбинации длиннее n отбрасываем, комбинации короче n дополняем числами 1 (которые не влияют на произведение). Например, для n = 3 получим:
1 1 60
1 2 30
1 3 20
1 4 15
1 5 12
1 6 10
2 2 15
2 3 10
2 5 6
3 4 5

Cчитаем суммы чисел каждой комбинаций (в моём примере - от 62 для первой до 12 для последней). Если одна из них равна x - да можно. Если ни одна из сумм не равна x - нет, нельзя.
FF
Fentestik Faantasy
53 491
Лучший ответ
Строго говоря эта задача не всегда имеет решение
например n=2, x=1, y=2
Для получения произведения равного 2 необходим как минимум один множитель равный 2, а если одно из слагаемых 2, второе слагаемое ( для суммы равной 1 ) должен быть равен -1, что не подходит по условию

А так навскидку предлагаю алгоритм:
Произведение раскладываем на множители, проверяем что x - сумма множителей == n-количество множителей -> нашли решение
AM
Alexander Miros
87 786
Несмотря на то, что задача на первый взгляд кажется сложной, её можно решить с помощью динамического программирования. Потребуется хранить массив dp[i][j], где i - кол-во выбранных чисел, а j - это сумма выбранных чисел. В каждой ячейке массива будет храниться произведение выбранных чисел, равное y.

Базовым случаем будет состояние dp[0][0] = 1 – это верно, так как ноль чисел с суммой 0 образуют произведение, равное 1.

Итак, двигаемся по массиву слева направо, сверху вниз и пытаемся увеличить текущую сумму на число num (где num меняется от 1 до минимума между текущей суммой и x). Если при этом произведение dp[i][j] * num не превосходит y и не превышает максимально возможного значения для чисел в памяти, обновляем значение в ячейке dp[i+1][j+num].

После того, как весь массив будет заполнен, проверяем значение в ячейке dp[n][x]. Если оно равно y, то такой набор чисел существует. Если нет, набор чисел найти невозможно.

Обратите внимание, что это решение требует большого количества операций и большого объема памяти для хранения массива. Оно "разумное" в том смысле, что оно эффективно использует память, но может быть очень медленным, особенно для больших значений n, x и y.

Также в среде реального времени этого алгоритма может не хватать для эффективного решения задачи из-за его вычислительной сложности и требований к памяти. Существуют эффективные алгоритмы для решения этой задачи, но они сложны в реализации и требуют хорошего понимания математики и алгоритмов.
Adam İballackov
Adam İballackov
25 860
По Пифагору
a2 + b2 = c2
Лёня Канев
Лёня Канев
1 686