我正在努力用C编写一个程序。 我想把一个数字(只有它可以被解体)分解成一个只能是斐波那契数的较小数字。 例如:
如果我有一个n = 20的数字,那么我的输出应该是1,1,2,3,5,8所以当我添加这些较小的斐波纳契数时,它给我20号。
答案 0 :(得分:2)
每个整数都有一个表示为唯一Fibonacci数的总和。这很容易通过归纳来证明:如果所有数字都存在这样的表示直到Fib(n),那么对于k中的1,2(......),Fib(n-1)的Fib(n)+ k具有表示Fib(n)+(k的表示)。证明了一个简单的递归算法,用于找到N的表示:选择小于N的最大Fibonacci数,比如它的Fib(k)。然后找到N-Fib(k)的表示。
答案 1 :(得分:0)
它可以简化为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
包含所有“候选者”,需要调用subset-sum算法来解决它,使用以下递归调用
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)
。