51 nod 1350 斐波那契表示

每一个正整数都可以表示为若干个斐波那契数的和,一个整数可能存在多种不同的表示方法,例如:14 = 13 + 1 = 8 + 5 + 1,其中13 + 1是最短的表示(只用了2个斐波那契数)。定义F(n) = n的最短表示中的数字个数,F(14) = 2,F(100) = 3(100 = 3 + 8 + 89),F(16) = 2(16 = 8 + 8 = 13 + 3)。定义G(n) = F(1) + F(2) + F(3) + ...... F(n),G(6) = 1 + 1 + 1 + 2 + 1 + 2 = 8。给出若干个数字n,求对应的G(n)。
Input
第1行:一个数T,表示后面用作输入测试的数的数量(1 <= T <= 50000)。
第2 - T + 1行:每行1个数n(1 <= n <= 10^17)。
Output
输出共T行:对应每组数据G(n)的值。
Input示例
3
1
3
6
Output示例
1
3
8
#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define F(i,a,b) for(int i=a;i<=b;++i)
#define R(i,a,b) for(int i=a;i<b;++i)
#define mem(a,b) memset(a,b,sizeof(a))

int t;
ll n;
ll f[101],A[101];
void init()
{
    A[2]=A[1]=1;
    f[1]=f[2]=1;
    F(i,3,84)
    {
        f[i]=f[i-1]+f[i-2];
        A[i]=A[i-1]+A[i-2]+f[i-2];
    }
}

ll solve(int id,ll num)
{
    if(f[id]==num) return A[id];
    if(f[id-1]>=num) return solve(id-1,num);
    return A[id-1]+num-f[id-1]+solve(id-2,num-f[id-1]);
}

int main()
{
    init();
    for(scanf("%d",&t);t--;)
    {
        scanf("%lld",&n);
        ll sum=0,ans=0;
        int id=0;
        while(sum+f[id+1]<n) sum+=f[++id];
        F(i,1,id) ans+=A[i];
        ans+=solve(id+1,n-sum);
        printf("%lld
",ans);
    }
    return 0;
}
View Code

不是太明白,贴了一下别人的代码供以后学习

原文链接

永远渴望,大智若愚(stay hungry, stay foolish)
原文地址:https://www.cnblogs.com/h-hkai/p/8207325.html