计划将一个数字分解为斐波纳契数

时间:2015-05-31 11:28:13

标签: c algorithm data-structures

我正在努力用C编写一个程序。 我想把一个数字(只有它可以被解体)分解成一个只能是斐波那契数的较小数字。 例如:

如果我有一个n = 20的数字,那么我的输出应该是1,1,2,3,5,8所以当我添加这些较小的斐波纳契数时,它给我20号。

2 个答案:

答案 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)