POI 2012 ROZ-Fibonacci Representation
给一个数,问最少可以用几个斐波那契数加加减减凑出来
例如 10=5+5 19=21-2
17=13+5-1
1070=987+89-5-1
题解:
贪心。
由于斐波那契数列有项为1,所以显然任何一个数都可以表示为若干斐波那契数列中项目的和。
那么既然如此,我们每次在斐波那契数列里找一个和(x)最接近的数,然后在(x)上加上/减去这个数,依此迭代直到(x)为0,这样的操作方式一定是最优的。
证明已经说过了,因为任意一个数都可以表示为斐波那契和,所以加减后的数仍然满足这一性质,而我们相当于通过局部最优拼出了全局最优。
所以没什么难点:
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
int p;
ll k;
ll fib[90];
void init()
{
fib[1]=1;
for(int i=2;i<=86;i++)
fib[i]=fib[i-1]+fib[i-2];
}
void dfs(ll x)
{
int p,q;
int ans=0;
while(x)
{
p=lower_bound(fib+1,fib+87,x)-fib;
q=p-1;
x=min(fib[p]-x,x-fib[q]);
ans++;
}
printf("%d
",ans);
}
int main()
{
scanf("%d",&p);
init();
while(p--)
{
scanf("%lld",&k);
dfs(k);
}
return 0;
}