POI 2012 ROZ-Fibonacci Representation

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\n",ans);
}
int main()
{
    scanf("%d",&p);
    init();
    while(p--)
    {
        scanf("%lld",&k);
        dfs(k);
    }
    return 0;
}
posted @ 2020-11-25 16:41  Seaway-Fu  阅读(80)  评论(0编辑  收藏  举报