Его можно уменьшить до subset-sum problem, где множество - число фибоначчи, меньшее/равно заданному числу.
Сначала сгенерируйте все числа меньше/равно заданному числу n
. C-подобный псевдокод:
int i = 1;
int* arr = //sufficiently large array
arr[0] = arr[1] = 1;
while (arr[i] <= n) {
i++;
arr[i] = arr[i-1] + arr[i-2];
}
После этого у вас есть arr
, который содержит все «кандидат», и необходимо вызвать алгоритм подмножества суммы, чтобы решить ее, используя следующие рекурсивные вызовы
D(x,i) = false x<0
D(0,i) = true
D(x,0) = false x != 0
D(x,i) = D(x,i-1) OR D(x-arr[i]-1,i)
позже вы, просто нужно повторить свои шаги и выяснить фактическое количество используемого DP:
Псевдо код:
x = n;
i = number_of_candidates;
while (i>0) {
if (x >= arr[i] && DP[i][x-arr[i]]) {
//arr[i] is in the solution, add it
x = x-arr[i];
}
i--; //do it for both cases, successful 'if' or not.
}
Общая сложность ответа - O(nlogn)
, а узким местом является решение DP.
Обратите внимание, что число «кандидатов» находится в O(logn)
, так как номер i
-й номер фибоначчи находится в O(phi^i)
.
Какой код вы писали? – byako
Тривиальным решением было бы написать любое число 'n' как сумму' n' единиц. –