给你数字 k
,请你返回和为 k
的斐波那契数字的最少数目,其中,每个斐波那契数字都可以被使用多次。
斐波那契数字定义为:
- F1 = 1
- F2 = 1
- Fn = Fn-1 + Fn-2 , 其中 n > 2 。
数据保证对于给定的 k
,一定能找到可行解。
思路:经过一番观察与尝试,发现可以每次贪心地选取不超过余量的最大Fibonacci数,组成分解。以下证明贪心法的正确性。
证:记Fibonacci数列的第i项为,设K的满足题意的分解为
。
一定为不超过K的最大Fibonacci数(记为
)。
若不是,则
因为不同时出现在分解中。(否则用
在原分解中替换
可以使项数减少,矛盾。)
矛盾!所以分解中必含 。可以使用上述贪心策略。
我的代码:
class Solution {
public:
int fd(int n){ //找出不超过n的最大Fibonacci数
//(注意到分解中的项数不会太多,所以想着省点空间)
int a=1,b=1;
while(b<=n){
int temp=b;
b=a+b;
a=temp;
}
return a;
}
int findMinFibonacciNumbers(int k) {
int cnt=0;
while(k){
k=k-fd(k);
cnt++;
}
return cnt;
}
};