• 51Nod 1350 斐波那契表示


    51Nod 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)。

    做法

    首先可以知道 fib(i-1)到fib(i)-1之间的数,一定是fib(i-1)与之前的数组合出的,那么考虑可不可以计算G(fib(i))
    G(fib(i)) = G(fib(i-1)) + (F(fib(i-1)+1)+...+F(fib(i)))

    除掉最后一项为1,其余的 F(fib(i-1)+1),...,F(fib(i)-1) 一共fib(i-2)-1个数
    他们的组合一定包含fib(i-1),因此贪心的考虑可以知道:
    F(fib(i-1)+1) = 1 + F(1)
    F(fib(i-1)+2) = 1 + F(2)
    F(fib(i-1)+3) = 1 + F(3)
    ...
    因此,可以得到
    G(fib(i))
    = G(fib(i-1)) + (1 + F(1) + 1 + F(2) + ... + 1+F(fib(i-2)-1) + 1)
    = G(fib(i-1)) + (F(1) + F(2) + ... + F(fib(i-2)-1)) + fib(i-2)
    = G(fib(i-1)) + G(fib(i-2)-1) + fib(i-2)
    现在考虑求任意G(n),通过类似的思想,可推出:
    G(n) = G(fib(m)) + G(n-fib(m)) + n - fib(m)
    2个式子n下降的速度与fib数列同级别,因此复杂度有保证。
    直接用map记忆化tle了,使用unordered_map通过

    #include <bits/stdc++.h>
    #define rep(i,a,b) for(int i=(a);i<=(b);++i)
    #define per(i,a,b) for(int i=(a);i>=(b);--i)
    #define pb push_back
    typedef long long ll;
    using namespace std;
    const int N = 100100;
    
    int sz;
    ll fib[N], n;
    unordered_map<ll,ll> isFib, ans;
    ll G(ll n) {
        if(n == 1) {return 1;}
        if(n == 2) {return 2;}
        if(n == 3) {return 3;}
        if(ans.find(n)!=ans.end())return ans[n];
        
        if(isFib.find(n) != isFib.end()) {
            int p = isFib[n];
            return ans[n] = fib[p-2] + G(fib[p-2]-1) + G(fib[p-1]);
        }
        else {
            per(i,sz,1)if(fib[i]<=n){
                return ans[n] = G(fib[i])+G(n-fib[i])+n-fib[i];
            }
        }
    }
    int main () {
        ios::sync_with_stdio(false); cin.tie(false);
        fib[0] = fib[1] = 1;
        isFib[fib[1]] = 1;
        rep(i, 2, 100) {
            fib[i] = fib[i-1] + fib[i-2];
            isFib[fib[i]] = i;
            if(fib[i] >= 1e17) {
                sz = i;break;
            }
        }
        int _; cin >> _; while(_--) {
            cin >> n;
            cout << G(n) << "
    ";
        }
        return 0;
    }
    
  • 相关阅读:
    Android 8.0 adb shell dumpsys activity activities | findstr mFocusedActivity 获取当前的 activity 显示空的
    spring-in-action_day01
    spring-in-action_day02
    spring-in-action-day04-配置属性 @ConfigurationProperties
    springmvc接收参数
    spring中Utils工具类注入问题
    Eclipse Push出现rejected
    Eclpis-cannot open git-receive-pack
    IO
    LinkedHashmap简要说明
  • 原文地址:https://www.cnblogs.com/RRRR-wys/p/13662452.html
Copyright © 2020-2023  润新知