zoukankan      html  css  js  c++  java
  • 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)
  • 相关阅读:
    游戏 黑白棋
    题解 P2472 【[SCOI2007]蜥蜴】
    题解 P1682 【过家家】
    题解 P3153 【[CQOI2009]跳舞】
    题解 P2763 【试题库问题】
    题解 P1345 【[USACO5.4]奶牛的电信Telecowmunication】
    网络流----最大流
    Tarjan缩点
    C#之抽象类
    C#之深复制学习案例
  • 原文地址:https://www.cnblogs.com/h-hkai/p/8207325.html
Copyright © 2011-2022 走看看