Меньше математического решения - использование динамического программирования c:
M = 1000
cache = {}
def dp(i, v, sum_of_digits):
if(i == M-1):
return sum_of_digits % 999 == 0 and v == 0
if((i, sum_of_digits) in cache):
return cache.get((i, sum_of_digits))
result = dp(i + 1, 0, sum_of_digits) + dp(i + 1, 9, sum_of_digits + 9)
cache[(i, sum_of_digits)] = result
return result
print(dp(0, 9, 9))
Вывод:
281853033550040537904406694735205583322614867369419355514834998793657889372557150681302072580895266688090267034276630517914503707145674628565136259594047883519869400688956077638702940707076342539608905721192230524534619011898800645140130344499642277977871480846234887754725793524573506157312565257
Пояснение :
Динами c алгоритм программирования работает на , запоминая полученные результаты В нашем случае это cache
dict
, которые хранят промежуточные результаты.
При каждом вызове у нас есть две возможности: 1) либо следующий di git равен 0; поэтому мы не увеличиваем sum_of_digits
; 2) или это 9; поэтому мы увеличиваем sum_of_digits
.
При каждом вызове мы запоминаем результаты, которые получаем, суммируя два промежуточных результата: dp(i + 1, 0, sum_of_digits), dp(i + 1, 9, sum_of_digits + 9)
.
мы завершаем работу при наличии M
количества цифр, возвращая True
, если sum_of_digits
по модулю 999 равно 0, а последний ди git v
равен 0.
Обратите внимание, что мы не проверяем первый ди git, потому что у нас всегда 9 в качестве первого ди git dp(0, 9, 9)
.
Примечание:
вам может потребоваться увеличить максимальную глубину рекурсии, используя:
sys.setrecursionlimit(XXXXXX..)
или вы можете преобразовать рекурсивное решение в итеративное (это всегда возможно сделать).
Хотя это решение более эффективно, чем решение методом перебора, @Thierry_Lathuille более эффективно чем это решение.