Вы можете использовать повторение:
T(0, m) = 0
T(n, m) = -Infinity (if n<0 or m<0)
T(n, m) = max(T(n-m*m, m-1)+1, T(n, m-1))
Или в коде Python:
from functools import lru_cache
@lru_cache(100000)
def T(n, m):
if n<0 or m<0: return (-1000000, 0)
if n==0: return (0, 0)
return max((T(n-m*m, m-1)[0]+1, m), T(n, m-1))
def squares(n):
s = int(n**0.5)
while n>0 and s>0:
_, factor = T(n, s)
yield factor**2
n -= factor**2
s = factor-1
for x in (4, 20, 38, 300):
result = list(squares(x))
print(sum(result), '= sum', result)
Пример, который вы привели (300), можно записать с 8 факторами как:
300 = 11² + 8² + 7² + 6² + 4² + 3² + 2² + 1²
Другие результаты:
4 = sum [4]
20 = sum [16, 4]
38 = sum [25, 9, 4]
300 = sum [121, 64, 49, 36, 16, 9, 4, 1]
person
Juan Lopes
schedule
06.10.2014
O(N*lg(n))
, где N — количество квадратов в сумме. - person Tacet   schedule 14.12.2014